指针与数组易错笔试题解析

回忆

sizeof()计算的是占用内存空间的大小,单位是字节,不关注内存中放的到底是什么
sizeof是操作符
strlen()是函数
strlen()计算的字符串长度,本质上统计的是’\0’之前的字符个数
数组名的意义:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

易错题

例1

char arr[] = {
    
    'a','b','c','d','e','f'};
printf("%d\n", strlen(arr));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));

1.arr表示首元素地址,由于没有’\0’作为字符串结束标志,它会一直向后计算,直到遇到’\0’ ,打印随机值
2.* arr表示’a’ ,strlen()参数接收的是一个字符指针,而’a’的ascii值是97,将97作为一个地址访问,这是一个未知的地址,会形成非法访问
3.&arr表示整个数组的地址,它的类型为char * [6],当传给strlen(),参数接收一个char * 的地址,那么会将数组指针强制类型转换为字符指针,但整个数组的地址在数值上也是首元素的地址,只不过&arr + 1, 跳过整个数组,打印随机值
4.&arr+1,跳过整个数组,向后继续访问,直到遇到’\0’ ,所以也会打印随机值,这个随机值与第一,三个打印的随机值相差6

例2

char *p = "abcdef";
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p+1));
  1. p[0] 可以解析为* (p + 0) , 即’a’ , 非法访问
  2. p中存放的&a,那么&p则为一个二级指针,即p的地址,从p的地址向后访问,由于p的地址未知,所以会打印随机值
  3. &p+1会跳过p这个变量,即跳过4个字节,因为p是一个指针,在32位平台下占4个字节,也会打印随机值

例3

int a[3][4] = {
    
    0};
printf("%d\n",sizeof(a[3]));

打印16,这里不存在数组的越界
原因有两点
例如

int a = 10;
short s = 11;
printf("%d\n",sizeof(s = a + 2));
printf("%d\n",s);

1.一个表达式或值拥有两个属性,一个是值属性,一个类型属性,而sizeof()计算的就是其类型属性,a是整形,2是整形,放入short里发生截断,这个表达式结果为short类型,大小为2
2.我们写出的如test.c文件,需要经过编译,链接变为test.exe来执行,表达式的计算也要在test.exe里进行运算,但遗憾的是在sizeof的运算是在编译过程就已经运算好了,sizeof(s = a + 2))直接变为2,s= a + 2在test.exe里不会存在了,当然也不会计算了

例4

int arr[3][4];
printf("%d",sizeof(*arr + 1));

arr代表首元素地址,即第一行地址&a[0],通过解引用的到第一行数组名a[0],a[0]没有单独放在sizeof内部,表示首元素地址,即&a[0][0] , &a[0][0] +1表示&a[0][1]

猜你喜欢

转载自blog.csdn.net/wan__xia/article/details/129647202