常见数组笔试题分析
一维数组
知识点回顾
1.数组名是数组1首元素的地址。
2.有两个例外:(1)sizeof(数组名)中这里的数组名是整个数组,计算的也是整个数组大小
(2)&数组名:这里的数组名表示整个数组的地址(但以首元素地址存在)
#include <stdio.h> int main() { int a[] = {1,2,3,4}; //a代表整个数组的大小,每个元素的大小为sizeof(int),所以这里是4*4=16 printf("%d\n", sizeof(a)); //a并未单独存在,所以这里a是首元素地址,a+0还是首元素地址,大小为(4/8)分两种平台 //32位为4,64位为8 printf("%d\n", sizeof(a + 0)); //*a是首元素,大小为int类型,因此为4 printf("%d\n", sizeof(*a)); //a+1是数组第二个元素地址,大小为(4/8) printf("%d\n", sizeof(a + 1)); //第二个元素大小为4 printf("%d\n", sizeof(a[1])); //整个数组的地址,但是以首元素地址呈现,因此为4 printf("%d\n", sizeof(&a)); //*与&相抵消,等效于a,因此是16 printf("%d\n", sizeof(*&a)); //&a+1跳过了一整个数组,虽然越界了,但是这里它的类型仍为int*,所以大小为(4/8) printf("%d\n", sizeof(&a + 1)); //首元素地址大小,(4/8) printf("%d\n", sizeof(&a[0])); //第二个元素地址,(4/8) printf("%d\n", sizeof(&a[0] + 1)); return 0; }
字符数组
知识点回顾:
1.strlen函数求字符串长,统计的是在字符串中'\0'之前的字符个数,如果没碰见'\0'就会一直向后面找。
2.strlen函数的参数部分需要传一个地址,当传递比如说是一个字符时,就是将该字符的Ascii码值传入,函数就从这个Ascii值开始统计,造成非法访问
#include <stdio.h> int main() { char arr[] = { 'a','b','c','d','e','f' }; //计算的是整个数组大小,为6*1 printf("%d\n", sizeof(arr)); //代表首元素地址 printf("%d\n", sizeof(arr + 0)); //*arr是首元素,解引用后大小为1 printf("%d\n", sizeof(*arr)); //数组第二个元素,所以是2 printf("%d\n", sizeof(arr[1])); //是数组地址,为(4/8) printf("%d\n", sizeof(&arr)); //跳过整个数组的地址,但还是地址,为(4/8) printf("%d\n", sizeof(&arr + 1)); //第二个元素的地址(4/8) printf("%d\n", sizeof(&arr[0] + 1)); return 0; }
#include <stdio.h> #include <string.h> int main() { char arr[] = { 'a','b','c','d','e','f' }; //arr是数组地址,strlen会一直向后找到'/0'再停止,此处未知'/0'在何处,所以是随机值 printf("%d\n", strlen(arr)); //arr + 0是首元素地址,其余同上,为随机值 printf("%d\n", strlen(arr + 0)); //*arr是首元素,此处传过去了'a'的Ascii码值,造成了非法访问 printf("%d\n", strlen(*arr)); //arr[1]是数组第二个元素,同上,造成了非法访问 printf("%d\n", strlen(arr[1])); //随机值 printf("%d\n", strlen(&arr)); //随机值 printf("%d\n", strlen(&arr + 1)); //随机值 printf("%d\n", strlen(&arr[0] + 1)); return 0; }
#include <stdio.h> #include <string.h> int main() { char arr[] = "abcdef"; //从首元素开始计算,遍历到第七个元素才找到'\0',不算上'\0',因此为6 printf("%d\n", strlen(arr)); //这块还是从首元素开始,同上,为6 printf("%d\n", strlen(arr + 0)); //*arr是首元素,造成非法访问,err printf("%d\n", strlen(*arr)); //数组第二个元素,同上,err printf("%d\n", strlen(arr[1])); //&arr代表数组地址(在这里是首元素地址),同上,为6 printf("%d\n", strlen(&arr)); //跳过一整个数组后的地址,由于不知道后面'\0'在哪,所以为随机值 printf("%d\n", strlen(&arr + 1)); //从第二个元素向后遍历,为5 printf("%d\n", strlen(&arr[0] + 1)); return 0; }
#include <stdio.h> #include <string.h> int main() { char* p = "abcdef"; //p是一个指针变量,(4/8) printf("%d\n", sizeof(p)); //p+1是'b'的地址,(4/8) printf("%d\n", sizeof(p + 1)); //*p是首元素,大小为1 printf("%d\n", sizeof(*p)); //p[0]->*(p+0),还是首元素,为一 printf("%d\n", sizeof(p[0])); //&p表示一级指针的地址,类型为char**,大小为(4/8) printf("%d\n", sizeof(&p)); //越过一个指针变量p的下一个地址,为(4/8) printf("%d\n", sizeof(&p + 1)); //&p[0] + 1是'b'的地址,为(4/8) printf("%d\n", sizeof(&p[0] + 1)); return 0; }
#include <stdio.h> #include <string.h> int main() { char* p = "abcdef"; //p表示a的地址,从此向后开始计数,为6 printf("%d\n", strlen(p)); //p+1表示b的地址,从此向后开始计数,为5 printf("%d\n", strlen(p + 1)); //*p表示首元素,非法寻址,err printf("%d\n", strlen(*p)); //同上,err printf("%d\n", strlen(p[0])); //&p表示一级指针p的地址,与原字符串无关系,因此是随机值 printf("%d\n", strlen(&p)); //同上,随机值 printf("%d\n", strlen(&p + 1)); //表示b的地址,所以为5 printf("%d\n", strlen(&p[0] + 1)); return 0; }
二维数组
#include<stdio.h> int main() { int a[3][4] = { 0 }; //整个数组的大小,为3*4*4=48; printf("%d\n", sizeof(a)); //数组第一行第一列的元素,大小为4 printf("%d\n", sizeof(a[0][0])); //将一行看为二维数组的一个元素,a[0]就是第一行这个一维数组的数组名,因此为4*4=16 printf("%d\n", sizeof(a[0])); //a[0]作为第一行数组名,没有单独放在sizeof内部,所以这里计算的可能是地址而不是数组 //a[0]可以看作首元素地址即a[0][0],+1表示第一行第二个元素的地址,大小为(4/8) printf("%d\n", sizeof(a[0] + 1)); //解引用后计算的是第一行第二个元素的地址,为4 printf("%d\n", sizeof(*(a[0] + 1))); //该数组的首元素类型为int(*)[4],a+1就是访问第二行的地址,为(4/8) printf("%d\n", sizeof(a + 1)); //解引用,表示的是第二行的元素,大小为16 printf("%d\n", sizeof(*(a + 1))); //&a[0]+1表示第二行的地址,为(4/8) printf("%d\n", sizeof(&a[0] + 1)); //解引用后表示第二行,大小为16 printf("%d\n", sizeof(*(&a[0] + 1))); //*a表示第一行元素,为16 printf("%d\n", sizeof(*a)); //这里a[3]虽然越界了,但sizeof这个关键字只运算,仅看内部类型,a[3]的类型为int[4],因此大小为16 printf("%d\n", sizeof(a[3])); return 0; }
好了,关于数组的题目就介绍到这里,下一篇将详细地讲一下指针笔试题,感谢各位未来大厂员工的支持!!!