2014-11-04
今天,偶遇到一C语言面试题,问题是求下面代码的输出:
int main(void)
{
char aa[][3] = {'a','b','c','d','e','f'};
char (*p)[3] = aa;
p++;
printf("%c\n",**p);
return 0;
}
标准答案是d
。由于太长时间没用过C语言了,有点懵,就把再学习c指针-int型指针及其他翻出来看了下。
下面一行一行解释下这段代码。
首先:
char aa[][3] = {'a','b','c','d','e','f'};
定义了一个2行3列的二维数组,我们把它想象成矩阵,第0行存储的是'a','b','c'
,第1行存储的是'd','e','f'
。当然,这六个元素在内存中是依次排列、紧紧挨着的。
然后:
char (*p)[3] = aa;
定义了一个名为p的数组指针
。数组指针
是指该指针指向一个数组,[3]指明被指向的数组最小的大小。另外,有一个指针数组
的概念,char *q[3]
是一个指针数组,q是一个具有3个元素的数组,每个元素是一个指向char类型变量的指针。
p
的默认值是aa
数组第0行第0列元素的地址,也就是aa
的首地址,p++
将p向下转移了一行,让p的值变成了aa
数组第1行第0列元素的地址,所以:
printf("%c\n",**p);
输出d
。
我在上面代码的基础上加了些冗余的代码,也许更容易理解:
# include <stdio.h>
# include <stdlib.h>
/*
*
*/
int main(int argc, char** argv) {
char aa[][3] = {'a','b','c','d','e','f'}; // aa[2][3]
int i,j;
for(i=0; i<2; i++) {
for(j=0; j<3; j++) {
printf("%c\n", aa[i][j]);
}
}
char (*p)[3] = aa; // 数组指针
printf("---\n");
printf("%p\n", p); //输出地址值,每次运行,结果可能不同
printf("%p\n", aa); // 和上一语句输出相同
printf("---\n");
printf("%c\n", (*p)[0]); //a
printf("%c\n", (*p)[1]); //b
printf("%c\n", (*p)[2]); //c
printf("%c\n", (*p)[3]); //d
printf("%c\n", (*p)[4]); //e
printf("---\n");
printf("%c\n",**p); //a
printf("%c\n",**(p+1)); //d
printf("%c\n",*(*(p+1)+1)); //aa[1][1]-> e
p++;
printf("%c\n",**p); //aa[1][0] -> d
return (EXIT_SUCCESS);
}
运行结果:
a
b
c
d
e
f
---
0x7fffa0bd1a70
0x7fffa0bd1a70
---
a
b
c
d
e
---
a
d
e
d