C + + 제 1 포인터와 참조

2009년 4월 19일 ·에 게시된 C / C + +

포인터와 참조 컴퓨터 과학에서 두 매우 중요한 개념입니다. 그들은 드레스 조금 다른 많은 프로그래밍 언어로 나타나지만 치료는 기본적으로 동일합니다. C + + 포인터에 필수적인 기술입니다.

포인터 변수와 같은 메모리에 다른 데이터 (또는 없음)으로 선언 수있는 데이터의 특별한 유형입니다. 타입 포인터의 변수는 메모리에 한 가지의 주소를 보유하고 있습니다. 이건 다른 사람 사이에 데이터 집합, 함수의 모든 변수, 상수, 시작하실 수 있습니다.

포인터 선언

포인터의 선언은 보통 변수 이름 앞에 *를 추가하여 이루어집니다. 우리가 상징 대신 "포인터 변수"의 "유형에 포인터"를 선언 있지만, 그들이 동일함을 말씀 유형의 이름을 붙여 널리 사용되는 표기법 *. 예를 들면 다음과 같습니다

  int로 / / 포인터.
 ptr_num1 ; INT * ptr_num1;

 / / 아니면.
 ptr_num2 ; INT * ptr_num2;

 이중에 / / 포인터.
 ptr_double1 ; * ptr_double1을 번;

 / / 아니면.
 ptr_double2 ; * ptr_double2을 번; 

일단 포인터가 존재 선언 길이를 가지고 있으며 결과적으로 메모리에서 이루어진다. 포인터의 크기는 일반적으로 32 비트 시스템에서 예를 들어 4 바이트에 대한 컴퓨터 / 시스템의 비트의 수를 동일합니다.

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 pc ; int i, * pi ; double d, * pd ; // O operador sizeof diz o tamanho do tipo do seu argumento. cout << "Size of char: " << sizeof ( c ) << " bytes" << endl ; cout << "Size of int: " << sizeof ( i ) << " bytes" << endl ; cout << "Size of double: " << sizeof ( d ) << " bytes" << endl ; cout << endl ; cout << "Size of char*: " << sizeof ( pc ) << " bytes" << endl ; cout << "Size of int*: " << sizeof ( pi ) << " bytes" << endl ; cout << "Size of double*: " << sizeof ( pd ) << " bytes" << endl ; 문자 C는 * PC, INT 나, * 파이, 더블 D, 경찰 * / / sizeof 연산자는 인수의 타입의 크기를 말한다 법정 << "문자의 크기 :". <<sizeof (C) << " 바이트 "<<endl; 법정 <<"정수의 크기 : "<<sizeof (I) <<"바이트 "<<endl; 법정 <<"이중의 크기 : "<<sizeof (D) <<"바이트 " <<endl; 법정 <<endl; 법정 << "문자 * 크기 :"<<sizeof (CP) << "바이트"<<endl; 법정 << "정수 * 크기 :"<<sizeof (PI) << "바이트"<<endl; 법정 << "이중의 * 크기 :"<<sizeof (PD) << "바이트"<<endl; 

포인터를 사용

그의 진술 후, 포인터의 내용은 변수와 같은 임의의 값을 메모리의 낭비입니다. 그것이 유용하기 위해서는 우리가 뭔가를 할당해야합니다. 포인터가 메모리 주소를 저장, 우리는 그것을 올바른 주소를 할당해야합니다.

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
  INT X, Y;
 px, * py ; INT * 픽셀 * 평;

 ; X = 13;
 ; Y = 10;

 x ; & X = 픽셀;
 y ; & Y = 평;

 42 ; * 픽셀 = 42;
 py ) ++ ; (* 평) + +;

 * px << endl ; 법정 <<* 픽셀 <<endl;
 * py << endl ; 법정 <<*<<endl;
 ( * px ) * ( * py ) << endl ; 법정 <<(* 픽셀) * (* 평) <<endl; 

연산자 & (앰퍼샌드 또는 앰퍼샌드 그의 이름은 '주소'이기 때문에 변수 이름 앞에)는, "주소"를 의미합니다.

무엇 평등 왼쪽의 것은 평등의 반대편에 똑같은 종류를 계속 할 수 있어야합니다. 포인터는 주소를 보유하고 있습니다. 그래서이 경우에는 포인터에 주소를 할당하기 위해서는 & 연산자로 주소를 얻어야합니다.

암시적 형식 변환 (예 : 숫자 형식 사이)가 경우를 제외하고, 컴파일 에러가 발생, 당신의 다른 유형 무언가에 변수를 할당합니다. 다행히도!

일단은 유효한 주소를 가리키는 포인터, 우리는 연산자 * (와 그 주소의 내용을 액세스할 수 있습니다 별표 누구의 공식적인 이름입니다), "드 참조 연산자."

성명에서 별표는 "형식으로 포인터"를 의미하며, 포인터의 내용을 읽기 쓰기의 맥락에서, 또는 "주소의 내용을"의미합니다 "내용이 임명합니다." 또한 산술 제품의 기호와 혼동하지 않도록주의하십시오. 혼동을 피하기 위해, 기억 연산자의 우선 순위 거대한 테이블을 방금 '눈'을 소비하고 망각에 떨어뜨린 것을. 여기 - 참조 연산자는 곱하기 연산자보다 우선순위가 높습 것을 발견할 것이다. 당신이 드 참조 연산자는 곱셈 연산자 이전 평가 기억 것입 완료.

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
  pa, * pb ; INT A, B, C, ** PB;
 ; = 2;
 ; B = 3;

 a ; PA = &;
 b ; BP = & B;

 pa * * pb ; C = * PA * PB;
 pa * * pb ; C = * PA * PB;
 pa * * pb ; C = * PA * PB;
 pa ** pb ; ** C * PA = PB;
 * pa ) * ( * pb ) ; C = (* PA) * (* BP);

 "Valor da Pegadinha: " << c << endl ; 법정 << "잡았다의 값 :"<<C <<endl; 

따라서 알고리즘의 증명이 예제의 마지막 5 라인 중 하나를 만드는 무엇을 청할 때, 당신은 PA와 PB로 지적 내용을 multiplies다고합니다. 그것에 대한 DP를 더 이상 필요! 정말 이렇게해야하는 경우 그리고 현실에서 위반, 당신은 4 세대가 과거와 미래 5 저장됩니다 파문 당신은 마지막 줄에를 사용하도록 선택하는 경우.

당신이 컨텐츠와 함께 할 수있는 일반적인 변수로 할 수있는 모든하거나 독서하거나 포인터가 const 것은 분명하지 않는 한 (작문, 포인터에 의해 지적하지만, 다른 폭언의 ...).

주소 및주의 사항

아래 코드를 :

  18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
  INT A, B;
 pa, * pb ; INT * PA * PB;

 "Antes de qualquer atribuição: \n " ) ; printf ( "모든 할당하기 전에 옵션 : \ n");

 "&a = %p \n " , & a ) ; // Endereço válido dado pelo SO. printf ( "& = % P \ N", & A) 운영 체제에 의해 지정된 / / 유효 주소를 입력합니다.
 "&b = %p \n " , & b ) ; // Endereço válido dado pelo SO. printf ( "& B = % P \ N", & b)는 OS에 의해 지정된 / / 유효 주소를 입력합니다.
 "&pa = %p \n " , & pa ) ; // Endereço válido dado pelo SO. OS에 의해 유효로 printf ( "& AP = % P \ N", & PA), / / 주소.
 "&pb = %p \n " , & pb ) ; // Endereço válido dado pelo SO. OS에 의해 주어진 printf ( "& SC = % P \ N", & BP) / / 유효 주소를 입력합니다.

 " \n " ) ; printf ( "\ N");

 "a = %d \n " , a ) ; // Conteúdo não inicializado (aleatório). printf ( "= % d 개 \ N") (무작위) 초기화되지 않은 / / 콘텐츠.
 "b = %d \n " , b ) ; // Conteúdo não inicializado (aleatório). printf ( "B = % d 개 \ N", B) / / 콘텐츠 (무작위) 초기화되지 않은.
 "pa = %p \n " , pa ) ; // Conteúdo não inicializado (aleatório). printf ( "PA = % P \ N", PA) / / 콘텐츠 (무작위) 초기화되지 않은.
 "pb = %p \n " , pb ) ; // Conteúdo não inicializado (aleatório). printf ( "SC = % P \ N", BP) / / 콘텐츠 (무작위) 초기화되지 않은.

 / / 다음과 같은 라인, 컴파일 및 실행을 uncommenting보십시오.
 / / Printf ( "* PA = % d 개 \ N", * PA) / / 무엇인가 (무작위 *)?
 / / Printf ( "* BP = % d 개 \ N", * BP) / / 무엇인가 (무작위 *)?

 " \n Após as inicializações dos ponteiros: \n " ) ; printf ( "\ N 포인터의 초기화 후 옵션 : \ n");

 a ; PA = &;
 b ; BP = & B;

 "&a = %p \n " , & a ) ; // Mesmo endereço válido dado pelo SO. printf ( "& = % P \ N", & A) 운영 체제에 의해 지정된 / / 비록 유효 주소를 입력합니다.
 "&b = %p \n " , & b ) ; // Mesmo endereço válido dado pelo SO. printf ( "& B = % P \ N", & b)는 OS에 의해 지정된 / / 비록 유효 주소를 입력합니다.
 "&pa = %p \n " , & pa ) ; // Mesmo endereço válido dado pelo SO. OS에 의해 주어진 printf ( "& AP = % P \ N", & PA) / / 비록 유효 주소를 입력합니다.
 "&pb = %p \n " , & pb ) ; // Mesmo endereço válido dado pelo SO. OS에 의해 주어진 printf ( "& SC = % P \ N", & BP) / / 비록 유효 주소를 입력합니다.

 " \n " ) ; printf ( "\ N");

 "a = %d \n " , a ) ; // Conteúdo não inicializado (aleatório). printf ( "= % d 개 \ N") (무작위) 초기화되지 않은 / / 콘텐츠.
 "b = %d \n " , b ) ; // Conteúdo não inicializado (aleatório). printf ( "B = % d 개 \ N", B) / / 콘텐츠 (무작위) 초기화되지 않은.
 "pa = %p \n " , pa ) ; // Conteúdo inicializado (&a). printf ( "PA = % P \ N", PA) / / 초기화 콘텐츠 (& A).
 "pb = %p \n " , pb ) ; // Conteúdo inicializado (&b). printf ( "SC = % P \ N", BP) / / 컨텐트 시작 (& B).

 "*pa = %d \n " , * pa ) ; // Conteúdo apontado por pa (*pa == a). PA에 의해 임명 printf ( "* PA = % d 개 \ N", * PA) / / 콘텐츠 (PA == *).
 "*pb = %d \n " , * pb ) ; // Conteúdo apontado por pb (*pb == b). printf ( "* BP = % d 개 \ N", * BP) / / BP 콘텐츠 (* BP == B)에 의해 지적했다.

 " \n Após as inicializações dos inteiros: \n " ) ; printf ( "\ N 정수의 초기화 후 옵션 : \ n");

 ; = 10;
 ; B = 13;

 "&a = %p \n " , & a ) ; // Mesmo endereço válido dado pelo SO. printf ( "& = % P \ N", & A) 운영 체제에 의해 지정된 / / 비록 유효 주소를 입력합니다.
 "&b = %p \n " , & b ) ; // Mesmo endereço válido dado pelo SO. printf ( "& B = % P \ N", & b)는 OS에 의해 지정된 / / 비록 유효 주소를 입력합니다.
 "&pa = %p \n " , & pa ) ; // Mesmo endereço válido dado pelo SO. OS에 의해 주어진 printf ( "& AP = % P \ N", & PA) / / 비록 유효 주소를 입력합니다.
 "&pb = %p \n " , & pb ) ; // Mesmo endereço válido dado pelo SO. OS에 의해 주어진 printf ( "& SC = % P \ N", & BP) / / 비록 유효 주소를 입력합니다.

 " \n " ) ; printf ( "\ N");

 "a = %d \n " , a ) ; // Conteúdo inicializado (10). printf ( "= % d 개 \ N") / / 초기화 컨텐츠 (10).
 "b = %d \n " , b ) ; // Conteúdo inicializado (13). printf ( "B = % d 개 \ N", B) / / (13) 콘텐츠를 초기화.
 "pa = %p \n " , pa ) ; // Conteúdo inicializado (&a). printf ( "PA = % P \ N", PA) / / 초기화 콘텐츠 (& A).
 "pb = %p \n " , pb ) ; // Conteúdo inicializado (&b). printf ( "SC = % P \ N", BP) / / 컨텐트 시작 (& B).

 "*pa = %d \n " , * pa ) ; // Conteúdo apontado por pa (*pa == a == 10). printf ( "* PA = % d 개 \ N", * PA) / / 컨텐츠 AP는 (* AP == == 10)에 의해 지적했다.
 "*pb = %d \n " , * pb ) ; // Conteúdo apontado por pb (*pb == b == 13). printf ( "* BP = % d 개 \ N", * BP) / / (* BP == B == 13) BP 콘텐츠에 의해 지적했다.

 " \n Alterando os valores através dos ponteiros: \n " ) ; printf ( "\ N 포인터를 통해 값을 변경합니다 : \ n");

 7 ; *= 7;
 42 ; * BP = 42;

 "&a = %p \n " , & a ) ; // Mesmo endereço válido dado pelo SO. printf ( "& = % P \ N", & A) 운영 체제에 의해 지정된 / / 비록 유효 주소를 입력합니다.
 "&b = %p \n " , & b ) ; // Mesmo endereço válido dado pelo SO. printf ( "& B = % P \ N", & b)는 OS에 의해 지정된 / / 비록 유효 주소를 입력합니다.
 "&pa = %p \n " , & pa ) ; // Mesmo endereço válido dado pelo SO. OS에 의해 주어진 printf ( "& AP = % P \ N", & PA) / / 비록 유효 주소를 입력합니다.
 "&pb = %p \n " , & pb ) ; // Mesmo endereço válido dado pelo SO. OS에 의해 주어진 printf ( "& SC = % P \ N", & BP) / / 비록 유효 주소를 입력합니다.

 " \n " ) ; printf ( "\ N");

 "a = %d \n " , a ) ; // Conteúdo inicializado (a == *pa == 7). printf ( "= % d 개 \ N") / / 초기화 컨텐츠 (* AP == == 7).
 "b = %d \n " , b ) ; // Conteúdo inicializado (b == *pb == 42). printf ( "B = % d 개 \ N", B) / / 초기화 컨텐츠 (* BP == B == 42).
 "pa = %p \n " , pa ) ; // Conteúdo inicializado (&a). printf ( "PA = % P \ N", PA) / / 초기화 콘텐츠 (& A).
 "pb = %p \n " , pb ) ; // Conteúdo inicializado (&b). printf ( "SC = % P \ N", BP) / / 컨텐트 시작 (& B).

 "*pa = %d \n " , * pa ) ; // Conteúdo apontado por pa ( 7). printf ( "* PA = % d 개 \ N", * PA) / / AP는 내용 (7)에 의해 지적했다.
 "*pb = %d \n " , * pb ) ; // Conteúdo apontado por pb (42). printf ( "* BP = % d 개 \ N", * BP) / / 내용은 BP (42)에 의해 지적했다. 

라인 18시 19분 respectivamnete 정수가 두 정수 두 포인터를 선언합니다.

라인 23-26는 내 변수의 주소를 표시합니다. 이러한 주소는 운영 체제에 의해 주어진 이러한 변수가 고정되는 동안. 변수는 프로그램 실행 중에 주소를 변경하지 않습니다,하지만 그 중 하나 구현에서 다른 변경할 수 있습니다. 누가이 주소는 프로그램 실행시 운영 체제 무엇이다 정의합니다. 컴파일러는 X 바이트는 각 변수에 필요한, ​​그리고 프로그램이이 공간을 줄 것이라는 해석 (타입)의 것을 알고.

30-33 라인은 초기화되지 않은이 변수의 내용을 보여줍니다. 그것은 누군가가 (내가 누군지 몰라) 컴퓨터 메모리에 그 장소를 놓고있는 지금은 내 변수에 속해있는 마지막 값은 쓰레기.

그들은 초기화되지 않은 PA와 PB로 지적 콘텐츠에 액세스하려고으로 36 37 주석 ​​라인에 안전합니다. 이러한 시도를하는 동안,이 프로그램은 INT 변수가 유효한 주소와 같은 임의의 쓰레기 그 가치를 해석하려고합니다. 컴파일러에 따라 운영 체제가 사용하고 그들의 운명은 무해하거나하지있을 수 있습니다. 어떤 특정한 것은이 라인의 결과는 문제의 예측 및 특정 소스는 것입니다.

라인 41 42 포인터는 정수 변수의 주소를 초기 A와 B 여기에서 지문이 반복됩니다.

예상했던 변경하지 마십시오 포인터의 주소를 참조하십시오. 의 내용 변경은 무엇인가. 변수 PA와 PB는 A와 B 각각의 주소를받을 수 있습니다. 손을의 내용이 정확히 A와 B가 프로그램의 시작 부분에 운영 체제에 의해 주어진 변수의 주소 값입니다. 이전 지문 확인하십시오. PA와 PB로 지적 내용 및 초기화되지 않은 B, 또는 쓰레기 같은 내용입니다. 그러나, 이전 단계와는 달리, 지금 유효한 주소와 그 내용 (A와 B의 주소)로 포인터 지점 A와 B 쓰레기 메모리 포인터 지금 이미 할당되었습니다 변수에 지점이 있습니다.

라인에 61 62 정수 변수는 다시와 인쇄 반복, 값을 10 13 초기화하고 있습니다.

이번에는 A와 B의 coteúdos는 더 이상 쓰레기 없습니다. 값은 잘 알려져 있습니다. 이전 단계와 관련 변수에만 값을 어드레싱에는 변화가 없다합니다.

A와 B가 초기화되었습니다 후, 내용 PA와 PB에 의해 지적되는 참조도 자동으로 변경됩니다. 이것은 PA와 PB 점 때문에 변수 PA와 PB가 사용하는 동일한 메모리 영역에 정확하게 발생합니다. 이것은 내용이 포인터에 의해 지적 그에 의해 지적 원래 변수의 내용을 변경하여 수정할 수 있습니다는 것을 의미합니다. 그리고 반대도 사실입니다 마지막으로, 라인이 81-97 표시, 즉, 변경 내용이 자동으로 원래 변수의 내용을 그들에 의해 지적을 변경, 포인터에 의해 지적했다.

그것은 코드를보고보다 포르투갈어 문구의 생각을 이해하는 것이 더 쉽습니다.

지금은 ...

이것은 포인터와 함께 기본적인 작업을했다. 이 예를 들어, 함수에 대한 포인터로 볼 수 흥미로운 것들은 여전히​​ 있지만, 좀 더 고급 주제로 간주됩니다 것을. 네 게시물 예정입니다이 시리즈, 다음, 포인터 및 참조 기능에 마지막으로 포인터 사이의 참조, 차이점과 유사성을 참조하십시오.

링크

댓글

  • http://blog.blabos.org/2009/05/ponteiros-e-referencias-em-c-parte-2/ 포인터와 참조 C + + 제 2 부 : 물집의 블로그 Blaber

    포인터와 참조에 대한 게시물 시리즈에서이 시도 다룰 것입니다 오늘 얘기를 시작 포인터 [...]로 [...]

  • http://www.caloni.com.br/blog/archives/ultimas-pesquisas-na-blogosfera-nacional Caloni.com.br»블로그 국립 블로그에 아카이브»최신 연구

    [...]의 [...]의 Pointeiros 및 참조

  • http://blog.blabos.org/2009/05/ponteiros-e-arrays/ 포인터 배열 : 물집의 Blaber 블로그

    이 시리즈의 [...] 첫 번째 게시물, 우리는 포인터에 대해 좀 얘기. 두 번째, 우리는 참조 말한다. 오늘 우리는 포인터와 [...] 사이의 친밀한 관계 (ui!)을 탐험합니다

  • 페르난도

    이봐, 당신은 그렇게 할 당신이 게시한 코드를 게시하는 방법을 가르쳐 있나요?
    상자 안에, 하이라이트 라인을 표시하고 언어의 키워드를 강조?

  • 페르난도

    이봐, 당신은 그렇게 할 당신이 게시한 코드를 게시하는 방법을 가르쳐 있나요?
    상자 안에, 하이라이트 라인을 표시하고 언어의 키워드를 강조?

  • http://blabos.pip.verisignlabs.com/ 공포

    문제 없어요!

    워드 프레스라는 플러그인이 WP - 구문 레이더에서 사용 GeSHi를 .

    당신은 속성의 "언어"와 "라인"을 추가 PRE 태그 안에 코드를 넣을 수 있습니다되면 설치되어 있어야합니다. 언어 자체 설명하며 문서에 언어의 목록을 가지고 라인이 시작 라인입니다.

    GeSHi는 위키에이 기능을 추가하는 데 사용할 수 있습니다.

    팁 : 코드를 복사하여 붙여넣하기 전에, 4 칸 모든 탭을 바꿉니다. 이것은 탭에 적용된 스타일의 코드를 독립적으로 만들 것입니다.

    포옹

  • http://blabos.pip.verisignlabs.com/ 공포

    문제 없어요!

    워드 프레스라는 플러그인이 WP - 구문 레이더에서 사용 GeSHi를 .

    당신은 속성의 "언어"와 "라인"을 추가 PRE 태그 안에 코드를 넣을 수 있습니다되면 설치되어 있어야합니다. 언어 자체 설명하며 문서에 언어의 목록을 가지고 라인이 시작 라인입니다.

    GeSHi는 위키에이 기능을 추가하는 데 사용할 수 있습니다.

    팁 : 코드를 복사하여 붙여넣하기 전에, 4 칸 모든 탭을 바꿉니다. 이것은 탭에 적용된 스타일의 코드를 독립적으로 만들 것입니다.

    포옹

  • 브루노 http://www.brunodanielmarinho.com

    같은 훌륭한 기사보기 희망 proxximos 게시물을 유지.

  • 브루노 http://www.brunodanielmarinho.com

    같은 훌륭한 기사보기 희망 proxximos 게시물을 유지.

Disqus에 의해 전원 블로그 코멘트