2012-07-26 2 views
1

이 코드는 인터넷의 어딘가에 있습니다. 프로그램의 출력은 문자열 문자열 문자열 다른 사람의 인수가 다를지라도 첫 번째 secon 및 세 번째 printf 문이 동일한 출력을 인쇄하는 이유를 설명해 주실 수 있습니까?c 프로그램 출력 설명

#include<stdio.h> 
int main() 
{ 
char a[2][3][3] = {'s','t','r','i','n','g'}; 
printf("%s\n", *a); 
printf("%s\n", a); 
printf("%s\n", **a); 
getchar(); 
return 0; 
} 
+0

@chris 배열의 총 크기는 18이고 6 개의 요소로 초기화되므로 이후 요소는 모두 '0'이됩니다. – ecatmur

+0

@chris 알아. 하지만 그물에서 찾은 코드는 직접 작성하지 않았습니다. – Prateek

+0

@ecatmur, 죄송합니다. 웬일인지 나는 모든 요소가 설정되고 있다고 생각했다. – chris

답변

8

이러한 3 차원 어레이, *a, a (배열 어레이의 배열)이기 때문에, 그리고 **a 모두 동일한 주소를 참조. 첫 번째 두 개는 형식이 printf() 인 경우 올바르지 않지만 모든 경우에 평이한 char * 문자열로 해석됩니다. 컴파일러에서 경고를 표시하면 일치하지 않는 형식 문자열 및 유형에 대한 일부가 표시됩니다.

*aa[0]이고 **aa[0][0]과 같습니다. 따라서 동일한 주소를 왜 참조하는지 쉽게 알 수 있습니다.

2

char (*)[3]char (*)[3][3]char *으로 처리하고 있습니다. 그들은 동일한 주소를 가리키고 (이 경우) 동일한 메모리 내 표현을 가지므로 그 주소를 가리키는 char *과 동일하게 읽혀집니다.

이것은 정의되지 않은 동작입니다. 하지 마.

1

어떻게 char a[2][3][3]이 메모리에 레이아웃되었는지 볼 수 있습니다. 내 컴퓨터에서는 다음과 같습니다.

0x7fffffffe220: 0x73 0x74 0x72 0x69 0x6e 0x67 0x00 0x00 
0x7fffffffe228: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
0x7fffffffe230: 0x00 0x00 

모든 배열이 실제로 선형이기 때문에 자연 스럽습니다. 이러한 차원의 의미는 a[i][j][k]과 같은 배열 인덱스를 사용하면 편리합니다. 그러나 메모리의 관점에서 볼 때 기본 주소에서 오프셋을 계산하는 것은 까다로운 방법입니다. 당신은 세 가지 차원 배열로 정의하기 때문에, 당신은 C 초기화 한 후이 배열을 처리하는 방법을 알고 할 수 있습니다 이제

:

{{{0x73, 0x74, 0x72}, {0x69, 0x6e, 0x67}, {0x0, 0x0, 0x0}}, {{0x0, 0x0, 0x0}, {0x0, 0x0, 0x0}, {0x0, 0x0, 0x0}}} 

이제 우리는 여기에서 무엇을 볼 수 있습니다 ...

Printf는 찌름을 인쇄하고 주소와 함께 전달됩니다. 그래서 printf와이 어떤 작업을 수행하는지, 그것은 널을 볼 때까지 주소를 잡은 하는 것입니다

같은 일이 있기 때문에 print에 대한 모든 호출 : 마지막으로

(gdb) x/10xb **a 
0x7fffffffe220: 0x73 0x74 0x72 0x69 0x6e 0x67 0x00 0x00 
0x7fffffffe228: 0x00 0x00 
(gdb) x/10xb *a 
0x7fffffffe220: 0x73 0x74 0x72 0x69 0x6e 0x67 0x00 0x00 
0x7fffffffe228: 0x00 0x00 
(gdb) x/10xb a 
0x7fffffffe220: 0x73 0x74 0x72 0x69 0x6e 0x67 0x00 0x00 
0x7fffffffe228: 0x00 0x00 

충고 한마디에 할 이 방법으로 코드. 당신이 충분히 똑똑하다면, 포인터만으로 모든 것을하십시오. 그러나 그것의 더 많은 오류가 발생하기 쉽습니다. 따라서 기본 레이어가 포인터와 배열을 거의 같은 방식으로 처리 할지라도 시작한 항목을 고수해야합니다. 손으로 물건을 조작 할 수 있다면 포인터와 같은 것을 다루십시오. 인덱스에 의한보다 엄격한 조작을 원한다면 배열과 같은 것들을 다루십시오.