2017-01-16 2 views
0
#include <stdio.h> 
#include <string.h> 

int main(){ 


// char* is a pointer 
    char str_a[20]; 
    char *pointer; 
    char *pointer2; 

    strcpy(str_a, "Hello, world\n"); 
    pointer = str_a; 
    printf(pointer); 

    pointer2 = pointer + 2; 
    printf(pointer2); 
    strcpy(pointer2, "y you guys!\n"); 
    printf(pointer); 
} 

안녕하세요, 저는 책을 읽고 있으며 이해할 수없는 포인터를 설명하는 프로그램을 접하게되었습니다. 이 책은 왜 이런 식으로 언급하지 않는 것 같아서, 더 나은 이해를 위해 다른 곳에서 상담해야한다는 것을 의미합니다. 위의 코드는 다음과 같은 출력을 생성합니다C 포인터 이해

Hello, world! (pointer) 
llo, world! (pointer2) 
Hey you guys! (pointer) 

내가 이해하지 못하는 변수 pointer 마지막 변화는 라인 (8)에 아직 pointer의 값이 명확의 마지막 줄에 변경을 볼 수 있다는 것입니다 산출.

출력의 두 번째 줄에 llo, world!이 아닌 pointer2의 값이 He으로 예상됩니다. 내가 생각할 수있는 유일한 것은 - 라인 14에서 + 2가 지정되면 포인터의 처음 두 바이트가 잘 리거나 나머지 바이트가 잘리고 첫 번째 두 바이트는 pointer에서 동일하게 유지됩니까?

하지만 이럴 수 없습니다. pointer2 = pointer + 2 아래에 printf(pointer)을 추가하면 출력이 "Hello, world!"입니다. 다시 "He"가 아닌

+3

C 포인터는 * 시작 *을 가리 킵니다. 그게 전부입니다. – usr2564301

+0

'pointer'도'pointer2'도 당신의 코드에서 포인터가 아닙니다. 올바르게 복사 했습니까? –

+0

컴파일러 경고를 활성화하고 모두 처리하십시오. 내 컴파일은 ** 9 ** 경고를 생성합니다 - 코드와 거의 같은 라인 수입니다. –

답변

2

모든 포인터의 첫 번째와 pointer2 포인터로 선언되지는이 '*'이 변수 전에 포인터로 선언이 있어야합니다. 비록 이것이 책에서 나온 것이라 할지라도 이것은 올바르지 않습니다.

는 내가 이해하지 못하는 것은 변수 포인터에 마지막 변경은 라인 (8)에 그러나 포인터의 값이 명확하게 출력의 마지막 줄에 변화를 볼 수 있다는 것입니다.

예! 그것이 포인터의 핵심입니다! pointer2포인터와 동일한 주소를 가지지 만 "pointer2 = pointer + 2;"에 할당 된대로 2 개의 요소 (배열 변수에는 해당 배열의 첫 번째 변수 주소가 들어 있음을 기억하십시오)가입니다. 따라서 "strcpy (pointer2,"y you guys! \ n ");" 명령은 다음에 뒤에 "012"를 복사하기 시작합니다. 포인터 2은 첫 번째 'l'을 가리 킵니다.

0

문자열에서 포인터는 으로 시작하고 끝이 아닌 문자열을 가리 킵니다.

문자열의 경우 끝은 null ('\0') 문자로 식별됩니다.

< * P는 점을 1000>

| 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 
    H  e  l  l  o  \0 
에 : 당신은 문자열, 말, *p 포인팅 "Hello"에 대한 포인터가있는 경우

그래서,이 문자열이 메모리에서 밖으로 누워 방법입니다 당신이 추가하면 2 p

지금, p 지금 1002 포인트 :

| 1002 | 1003 | 1004 | 1005 | 
    l  l  o  \0 

을 그래서, 분명히, accessi ng p을 문자열 포인터로 사용하면 "llo"가됩니다. 당신이 조기에 문자열 을 할 경우 대상 문자 '\0'로 설정해야합니다

char mystr[10] = "Hello"; 
char *p = mystr; 
*(p+2)='\0'; 

지옥, 당신도 그렇게 포인터가 필요하지 않습니다. \0을 종료 할 때까지 당신은 너무, C에서 문자열이 0 바이트 (\0) 종료, 그래서 당신이 pointer 및 인쇄 pointerstr_a를 할당 할 때 프린터가 첫 번째 주소에서 pointer 포인트를 이동합니다, 지금

+0

NULL이 아님, NUL - 다른 답변에 대한 내 더 긴 코멘트를 참조하십시오. –

1

mystr[2] = '\0';을 수행 할 수 있습니다 모든 텍스트를 인쇄합니다.

그러나 pointer2pointer의 가치 플러스 2를 할당 할 때, 당신은 어디에 pointer 점 후 2 개 주소를 가리 킵니다 확인하고 인쇄 할 때 당신은 종료 \0까지 Hellol에서 시작합니다.

그리고 세 번째를 들어, pointer2"y you guys!\n"와 점, 그래서 전에 두 개의 주소 (pointer 점)에서 시작하여 전체 문자열이 당신이 얻은 결과로 이어지는 "Hey you guys!\n" 것 곳에서 메모리의 내용을 대체

.

H e  l l o , w o r l d \n  // start from pointer 
^ pointer 

H e  l l o , w o r l d \n  // start from pointer2 
^ pointer^pointer2 

H e  y y o u g u y s ! \n // start from pointer 
^ pointer^pointer2 
+0

OK - 내 댓글이 삭제되었습니다. 앱의 업데이트 내역을 검사하기는 어렵습니다. –

+0

C 문자열은 "null terminated"이 아닙니다. NULL은 포인터 값입니다. C 문자열은 값이 0 인 바이트로 끝나며 대개는 ''\ 0 ''으로 기록됩니다. ASCII 문자 표준에서이 0 값 바이트는 "NUL"(하나의 "L")이라고하지만이 이름을 사용하면 분명한 이유 때문에 혼동을 야기합니다. "0"또는 "0 바이트"또는 이와 유사한 것이 더 낫습니다. –

+0

@JohnHascall이 설명에 감사드립니다! 결정된. – Uriel

1

pointerpointer2와 기본적으로 동일한 메모리 청크 가리. 그것은 말했다 초기 상태는 다음과 같이이다 :

p  p2 
H e l l o , w o r l d \n \0 

은 그럼 당신은 p2에서 청크을 덮어 쓰기가된다 :
p  p2 
H e y y o u g u y s \n \0 

이 차트 이해 바랍니다. 포인터를 인쇄하면 항상 배열 끝에 도달하게됩니다 ( \0).

+1

이것은 마지막 출력을 잘 설명합니다. – artm

+1

OP에 대한 좋은 대답이지만, 물론'char * '에 대해서만 유효합니다. 특히 C 문자열 유형의 경우에 유효합니다. ("포인터를 인쇄 할 때마다 ...") – usr2564301