【C语言笔试复习】指针数组和数组指针

这周开始作C语言笔试卷,什么嘛!考的都是概念,各类细节,虽然貌似书上都能找到,但我还真不清楚...顿时又有一种我C语言学的好渣的感受 T_T数组

好了,说下在【上机实验蓝皮书背后,综合测试题二】中难到的2道题,这两道题使得你对【指针数组】和【数组指针】的区别更加清晰。函数

【例题1】测试

有如下程序:spa

1 #include <stdio.h>
2 
3 int main()
4 {
5     char *s[] = {"one", "two", "three"}, *p;
6     p = s[1];
7     printf("%c, %s\n",*(p+1), s[0]);
8     return 0;
9 }

执行后的结果是_______。指针

A. n, two      B. w, one     C. t, one  D. o, twocode

第一次我选了 C,由于我觉得 (p+1) 是指向 "three“ 的。这是对指针 p 类型的理解错误。blog

正确答案是 B,由于: three

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     char *s[] = {"one", "two", "three"}; // s是一个指针数组,元素是3
 6                                          // 个指向字符串常量的指针
 7     char *p = s[1];  // p是一个指向字符串的指针变量
 8     printf("%c, %s\n",*(p+1), s[0]);
 9     // (p+1)是p的地址加一个字符内存的大小,从指向t变成指向w
10     return 0;
11 }
因此,平时咱们说的指向字符串的指针,其实都是指向一个字符,因此对它进行位移运算时,加减都是1。

另外,若是你把第8行内存

    printf("%c, %s\n",*(p+1), s[0]);

 改为   字符串

    printf("%c, %s\n",*(p+1), s[0]);

输出就会是:wo,one

由于平时咱们输出字符串的时候,实际上都是把字符串的首地址传给 printf( ) 函数,它经过末尾的 '\n',来判断是否结束。

 

【例题2】

1 #include <stdio.h>
2 
3 int main()
4 {
5     int a[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
6     int (*p)[4] = a;
7     printf("%d\n", *(*(p+1)+3));
8     return 0;
9 }

以上代码执行的结果是_______。

答案是 8 

这道题初看我彻底不理解...怎么*了还能*,(*p)[4]又是什么鬼...我作这份卷子前把【指针数组】和【数组指针】搞乱了= 

是这样的:

1.(*p)[4]:声明p是一个指向(4个int元素的数组)的指针,所以 p+1 从指向 a[0],变成指向 a[1]

2.*(*(p+1)+3):为何会有两个星?

*(p+1) => a[1][0](也就是5),第一星从a[1]变成a[1][0],这个过程虽然地址没有变,但指针的类型变了!原来指针+1是加4个 int,如今指针+1只加一个 int 了!!

*(p+1)+3 => a[1][3](也就是8),再取一个*就是从地址里读出8

还能够修改一下原来的代码弄清楚:

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     int a[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
 6     int (*p)[4] = a;   
 7     printf("p: %p\n",p);
 8     printf("p+1: %p\n",p+1);
 9     printf("*(p+1): %p\n",*(p+1));
10     printf("*(p+1)+3: %p\n",*(p+1)+3);
11     printf("%d\n",*(*(p+1)+3));
12     return 0;
13 }

输出的结果是:

p: 0x7fff9f4ba180
p+1: 0x7fff9f4ba190
*(p+1): 0x7fff9f4ba190
*(p+1)+3: 0x7fff9f4ba19c
8

好啦~

相关文章
相关标签/搜索