常见数组笔试题分析
一维数组
知识点回顾
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;
}
好了,关于数组的题目就介绍到这里,下一篇将详细地讲一下指针笔试题,感谢各位未来大厂员工的支持!!!