赞
踩
尊贵的各位大厂码农你们好,是的,没错,我又来找你们来帮我指正文章了,今天的主题是数组和指针的笔试题专栏,大家给掌掌眼,有问题的话还请帮忙斧正哦!
目录
首先,在开始笔试题之前,首先得了解一下几个问题:
1,sizeof()的作用是求对象所占空间的大小,单位是字节。
2,数组名的几种不同用法所代表的含义,一般情况下数组名代表的是首元素地址,但有两种例外情况,首先sizeof(数组名),这里的数组名代表整个数组。其次取地址数组名,代表的是整个数组的地址。
对于倒数第三个题有一点要强调一下,就是它跳过了整个数组,但是数组后面的地址空间是未知的,是不是我们这里再求作所占空间大小就是有问题的,答案是并不是,后面的地址只能说我们没访问权限。但是这块地址空间是一定存在的,所以就是单纯的求这块地址空间的大小。
还有*&a,如果是放在sizeof内部,他其实就是相当于sizeof(a),求整个数组的大小,但是如果是放在外面用的话,就是相当于拿到整个数组,也就是数组名,等价于首元素地址。这里二者处在不同位置,含义是不一样的
对于第三个第四个这种情况,因为你拿到的是字符,比如字符a,对应ascii码就是97,那站在strlen(),你把97传给我,我就把它当成一个地址,但是首先97这个地址编号存不存在,用户能否访问都是一个问题,所以可能就会出现非法访问的问题。
到这里可以给sizeof() 与 strlen() 做一个总结:
sizeof()是一个操作符,返回值类型为size_t的无符号类型,他的作用就是计算对象所占内存空间的大小,不在乎内存中放的什么。
strlen()是一个函数,是用来计算字符串长度的,从给定的地址向后访问 ,直至到\0停止。
对于二维数组,这里重点需要注意几个点:
1,注意区分二维数组数组名与第一行的数组名,也就是上面的a 与 a[0],前者表示的是二维数组的首元素的地址,是第一行的地址,而后者表示的是第一行的第一个元素的地址。二者数值一样,但是意义不一样。
2,对于sizeof而言,他只是求对象所占内存空间的大小,他的求值依据是对象的类型,而不是真正的会去访问这块内存空间。所以在最后的sizeof(a[3])里面,看似好像越界访问数组了,因为数组只有三行,但是实际上我们并没有真正的访问这块空间,只是说假如有这么一块空间是int [4]类型,然后让你求这块空间所占内存空间的大小。
- int main()
- {
- int a[5] = { 1, 2, 3, 4, 5 };
- int *ptr = (int *)(&a + 1);
- printf( "%d,%d", *(a + 1), *(ptr - 1));
- return 0;
- }
大家觉得结果是什么? 没错,就是2,5,至于为什么是这样,解析如下:
- struct Test
- {
- int Num;
- char* pcName;
- short sDate;
- char cha[2];
- short sBa[4];
- }*p;
- //假设p 的值为0x100000。 如下表表达式的值分别为多少?
- //已知,结构体Test类型的变量大小是20个字节
- int main()
- {
- p = (struct Test*)0x100000;
- printf("%p\n", p + 0x1);
- printf("%p\n", (unsigned long)p + 0x1);
- printf("%p\n", (unsigned int*)p + 0x1);
- return 0;
- }
首先,定义的p是一个结构体指针,已知他的地址是0x100000。这个题的主要考查点就是不同指针类型,加上整数,移动的步长不同。
解析:
注意%p是让我们用地址的形式打印数据,并不是去找这个地址,所以对于第二个结果而言,他只是用地址的形式打印输出。至于为什么前面会补0,是因为这是在32位系统下,你输出展示得有四个字节,所以前面你得补上两个0,如果打印完全,以第一个为例应该是00000000000000000000000000100014,一共满32位。
- int main()
- {
- int a[4] = { 1, 2, 3, 4 };
- int *ptr1 = (int *)(&a + 1);
- int *ptr2 = (int *)((int)a + 1);
- printf( "%x,%x", ptr1[-1], *ptr2);
- return 0;
- }
解析:
%x表示以十六进制不带前缀的格式输出结果,所以最后的输出是4,2000000。这里我们小总结一下,%p是以地址形式输出,结果前面会补0,%x是以十六进制不带前缀的格式输出,前面不进行任何补充,如果是%#x,输出结果前面加0x.
- #include
- int main()
- {
- int a[3][2] = { (0, 1), (2, 3), (4, 5) };
- int *p;
- p = a[0];
- printf( "%d", p[0]);
- return 0;
- }
这个题的结果是什么先不说,只能说这个题有个大坑可能等着你掉进去呢!
仔细看这个数组,长得倒是有模有样的,但是内部不纯,里面放的是逗号表达式,所以结果可不是简简单单的0,那么让我们解析解析:
- int main()
- {
- int a[5][5];
- int(*p)[4];
- p = a;
- printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
- return 0;
- }
解析:
- int main()
- {
- int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- int *ptr1 = (int *)(&aa + 1);
- int *ptr2 = (int *)(*(aa + 1));
- printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
- return 0;
- }
解析:
- int main()
- {
- char *a[] = {"work","at","alibaba"};
- char**pa = a;
- pa++;
- printf("%s\n", *pa);
- return 0;
- }
这个题考察的一个点就是将字符串赋值给一个字符数组的时候,本质上不是将一整个字符串存进数组中,存放的只是字符串首元素地址。
- int main()
- {
- char *c[] = {"ENTER","NEW","POINT","FIRST"};
- char**cp[] = {c+3,c+2,c+1,c};
- char***cpp = cp;
- printf("%s\n", **++cpp);
- printf("%s\n", *--*++cpp+3);
- printf("%s\n", *cpp[-2]+3);
- printf("%s\n", cpp[-1][-1]+1);
- return 0;
- }
解析:
今天的文章就到这了,如果大家觉得还可以的话,还请帮忙三连三连哦,十分感谢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。