> 文档中心 > 【关于指针和数组的笔试题】

【关于指针和数组的笔试题】

我们先回顾一些知识点: 1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址
3. C 库函数 size_t strlen(const char *str) 计算字符串 str 的长度,直到找到\0结束。

文章目录

  • 一、一维数组笔试题
  • 二、字符数组笔试题
  • 三、二维数组

一、一维数组笔试题

来看下面的几行代码,猜测会输出什么结果

//一维数组int a[] = { 1,2,3,4 };printf("%d\n", sizeof(a));printf("%d\n", sizeof(a + 0));printf("%d\n", sizeof(*a));printf("%d\n", sizeof(a + 1));printf("%d\n", sizeof(a[1]));printf("%d\n", sizeof(&a));printf("%d\n", sizeof(*&a));printf("%d\n", sizeof(&a + 1));printf("%d\n", sizeof(&a[0]));printf("%d\n", sizeof(&a[0] + 1));

解析:

1.sizeof(a),a是数组名,所以计算的是整个数组的大小,数组类型为int,其中含有4个元素所以打印结果为16
2.sizeof(a+0),数组名a没有单独放在sizeof部内部,a+0表示数组首元素地址,所以打印结果为4/8,在32位平台下为4,在64为平台下为8.
3.数组名a是首元素地址,*a对a解引用得到数组的首元素也就是1,所以打印结果为4
4.a+0为数组第一个元素地址,同理a+1是数组第二个元素地址,所以结果也是4/8.
5.a[1]是数组第二个元素,是int类型,所以打印结果为4.
6.&a取出的是数组首元素地址,同理所以打印结果为4/8.
7.对&a解引用,得到的是整个数组,相当于sizeof(a),打印结果为16.
8.&a得到的是整个数组的地址,而在这个地址上+1相当于跳过了整个数组,指向该数组后面的地址,也是地址所以打印结果为4/8.
9.&a[0],拿到的是数组首元素的地址,所以打印结果为4/8.
10.&a[0]是数组首元素地址,+1得到的是数组第二个元素的地址,也是地址,所以打印结果为4/8.

二、字符数组笔试题

来看下面的几行代码,猜测会输出什么结果

//字符数组char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", sizeof(arr));printf("%d\n", sizeof(arr + 0));printf("%d\n", sizeof(*arr));printf("%d\n", sizeof(arr[1]));printf("%d\n", sizeof(&arr));printf("%d\n", sizeof(&arr + 1));printf("%d\n", sizeof(&arr[0] + 1));

解析:

1.arr是数组名,sizeof(arr),计算的是整个数组大小,类型为char,所以结果是6.
2.数组名arr没有单独放在sizeof部内部,arr+0表示数组首元素地址,所以打印结果为4/8。
3.数组名arr是首元素地址,*arr对arr解引用得到,数组第一个元素a,所以打印结果是1.
4.arr[1]表示数组第二个元素,所以打印结果是1.
5.&arr取出的是整个数组的地址,是地址就是4/8.
6.同理&arr+1跳过了整个数组,指向的是f后面的地址,是地址就是4/8.
7.&arr[0]+1,表示的数组第二个元素的地址,所以结果是4/8

代码如下(示例):

printf("%d\n", strlen(arr));printf("%d\n", strlen(arr + 0));printf("%d\n", strlen(*arr));printf("%d\n", strlen(arr[1]));printf("%d\n", strlen(&arr));printf("%d\n", strlen(&arr + 1));printf("%d\n", strlen(&arr[0] + 1));

解析:

1.arr数组中没有\0,所以strlen函数会继续往后找\0统计\0之前出现的字符个数所以结果肯定是一个大于6的随机值。
2.arr + 0是数组首元素的地址,而arr中仍然没有\0,所以还是随机值
3.arr是数组首元素的地址,*arr是数组的首元素,‘a’-97strlen接收的是一个地址而字符a的ASCI码值为97传过去97,此时是错误的
4.同理arr[1]是字符b,b的ASCI值为98,传过去98,此时是错误的
5.&arr是数组的地址,strlen函数会继续往后找\0统计\0之前出现的字符个数所以结果肯定是一个随机值。
6.同理&arr+1,跳过整个数组,strlen仍然会找\0,所以结果仍然是一个随机值。
7.&arr[0] + 1取出首元素的地址+1,指向第二个元素b,从b位置开始找\0,所以结果还是一个随机值。

来看下面的几行代码,猜测会输出什么结果

char arr[] = "abcdef";//内存中存放的是a b c d e f \0printf("%d\n", sizeof(arr));printf("%d\n", sizeof(arr + 0));printf("%d\n", sizeof(*arr));printf("%d\n", sizeof(arr[1]));printf("%d\n", sizeof(&arr));printf("%d\n", sizeof(&arr + 1));printf("%d\n", sizeof(&arr[0] + 1));

解析:

1.sizeof(arr)计算的是整个数组大小,数组中存放的是a b c d e f \0,所以结果是7
2.arr+0表示的是数组首元素地址是地址就是4/8
3.*arr解引用后得到的是数组首元素,首元素是一个字符,大小是一个字节,所以结果是1
4.arr[1]是数组的第二个元素,大小是1个字节,所以结果是1
5.&arr是数组的地址,是地址就是4/8
6.&arr + 1是从数组地址开始向后跳过了整个数组产生的一个地址,是地址就是4/8
7.&arr[0] + 1 是数组第二个元素的地址,是地址就是4/8

来看下面的几行代码:

char arr[] = "abcdef";//内存中存放的是a b c d e f \0printf("%d\n", strlen(arr));printf("%d\n", strlen(arr + 0));printf("%d\n", strlen(*arr));printf("%d\n", strlen(arr[1]));printf("%d\n", strlen(&arr));printf("%d\n", strlen(&arr + 1));printf("%d\n", strlen(&arr[0] + 1));

1.strlen计算的是\0之前出现的字符个数所以结果是6
2.arr+0是首元素地址,从首元素开始向后找\0,所以结果也是6
3.strlen接收的是一个地址,然而而字符a的ASCI码值为97,传过去97,此时是错误的
4.同理arr[1]是字符b,b的ASCI值为98,传过去98,此时是错误的
5.&arr取出的是数组的地址,从最开始向后数字符,所以结果是6
6.&arr + 1跳过了整个数组,跳过了\0,所以结果是随机值
7.&arr[0] + 1,取出首元素的地址+1得到第二个元素地址,相当于从b开始向后数,直到找到\0\为止所以结果是5

三、二维数组

来看下面的几行代码:

//二维数组int a[3][4] = { 0 };printf("%d\n", sizeof(a));printf("%d\n", sizeof(a[0][0]));printf("%d\n", sizeof(a[0]));printf("%d\n", sizeof(a[0] + 1));printf("%d\n", sizeof(*(a[0] + 1)));printf("%d\n", sizeof(a + 1));printf("%d\n", sizeof(*(a + 1)));printf("%d\n", sizeof(&a[0] + 1));printf("%d\n", sizeof(*(&a[0] + 1)));printf("%d\n", sizeof(*a));printf("%d\n", sizeof(a[3]));

1.计算的是整个数组的大小,单位是字节3* 4* 4 = 48所以结果是48
2.a[0][0]表示 第1行第一个元素的大小所以结果是4
3.a[0]是第一行的数组名,sizeof(a[0])就是第一行的数组名单独放在sizeof内部,计算的是第一行的大小,所以结果是16
4.a[0]作为第一行的数组名,并没有单独放在sizeof内部,也没有被取地址,所以a[0]就是数组首元素的地址,就是第一行第一个元素的地址,a[0]+1就是第一行第二个元素的地址所以结果是4/8
5.*(a[0] + 1))表示的是第一行第二个元素,所以结果是4
6. a表示首元素的地址,a是二维数组,首元素的地址就是第一行的地址所以a表示的是二维数组第一行的地址,a+1就是第二行的地址,是地址所以结果是4/8
7. 对第二行的地址解引用访问到就是第二行所以结果是16
8. a[0]是第一行的数组名,&a[0]取出的就是第一行的地址,&a[0] + 1 就是第二行的地址是地址所以结果是4/8
9. 对第二行的地址解引用访问到就是第二行,所以结果是16
10. a就是首元素的地址,就是第一行的地址,*a就是第一行所以结果是16
11.我们数组一共三行,为什么这里是a[3]呢?是不是出问题了呢?实际上不是这样的,sizeof不会访问内存,也就是不会去找第四行,我们只要知道他的类型是int[4],所以结果是16


以上就是关于指针和数组的一些笔试题