指针使c语言中比较难的一类题目,在很多面试题目上也经常能够看到,下面我们一起来看一些与指针有关的面试题。首先,在做题之前,我们需要了解数组名的一些相关知识,1.sizeof括号里单独放一个数组名,这个数组名表示整个数组;2.&数组名中的数组名表示整个数组;3.除此之外,其它的数组名表示数组首元素地址。
注:以下结果均为x86环境下的结果
一、一维数组
int a[] = {1,2,3,4};
1.printf("%d\n",sizeof(a));
2.printf("%d\n",sizeof(a+0));
3.printf("%d\n",sizeof(*a));
4.printf("%d\n",sizeof(a+1));
5.printf("%d\n",sizeof(a[1]));
6.printf("%d\n",sizeof(&a));
7.printf("%d\n",sizeof(*&a));
8.printf("%d\n",sizeof(&a+1));
9.printf("%d\n",sizeof(&a[0]));
10.printf("%d\n",sizeof(&a[0]+1));
1.sizeof内单独放一个数组名a,故a表示整个数组,该数组有4个元素,每元素为4个字节,故结果为16;
2.sizeof内并不是单独一个数组名,故a表示数组首元素地址,只要是地址,其大小就为4;
3.a为数组首元素地址,解引用得到数组首元素1,1的大小为4;
4.a为数组首元素地址,a+1跳过一个整形,为第二个元素的地址,地址的大小为4;
5.a[1]为数组第二个元素,大小为4;
6.&a为真个数组的地址,地址的大小为4;
7.*&a(相当于a),a表示整个数组,大小为16;
8.&a+1跳过整个数组,是一个地址,大小为4;
9.&a[0]为第一个元素的地址,大小为4;
10.&a[0]+1跳过一个整形,为第二个元素的地址,大小为4;
运行结果如下:
二、字符数组
(1)代码1
char arr[] = {'a','b','c','d','e','f'};
1 printf("%d\n", sizeof(arr));
2 printf("%d\n", sizeof(arr+0));
3 printf("%d\n", sizeof(*arr));
4 printf("%d\n", sizeof(arr[1]));
5 printf("%d\n", sizeof(&arr));
6 printf("%d\n", sizeof(&arr+1));
7 printf("%d\n", sizeof(&arr[0]+1));
1.sizeof里单独一个arr,表示整个数组,数组有6个元素,每个元素大小为1,故结果为6;
2.arr表示数组首元素地址,地址的大小为4;
3.arr表示数组首元素地址,解引用得到数组首元素,大小为1;
4.arr[2]为数组第二个元素,大小为1;
5.&arr表示整个数组的地址,大小为4;
6.&arr+1跳过整个数组,是一个地址,大小为4;
7.&arr[0]+1表示第二个元素的地址,大小为4;
运行结果如下:
(2)代码2
char arr[] = {'a','b','c','d','e','f'};
1 printf("%d\n", strlen(arr));
2 printf("%d\n", strlen(arr+0));
3 printf("%d\n", strlen(*arr));
4 printf("%d\n", strlen(arr[1]));
5 printf("%d\n", strlen(&arr));
6 printf("%d\n", strlen(&arr+1));
7 printf("%d\n", strlen(&arr[0]+1));
做题之前,需要注意此处不在使用sizeof计算数组或元素大小了,而是使用strlen来计算字符串的长度,strlen的特点是它是一个库函数,传给strlen的参数必须是一个地址,否则系统将会报错,且它在遇到\0时即停止计算,计算的长度不包括\0。
1.arr表示数组首元素,因为数组arr中没有\0,因此结果为随机值,最小为6;
2.同1;
3.arr表示数组首元素地址,*arr即为数组首元素,但strlen要求参数必须为一个地址,因此这段代码是错误的;
4.同3,arr[1]为数组第二个元素,不是一个地址,代码错误;
5.&arr为数组第二个元素的地址,其数值与arr一样(它们的区别知识在运算是跳过的字节不一样),但是strlen是一个字节一个字节计算长度的,但由于没有\0,结果为随机值,最小为6(结果与1相同);
6.&arr+1跳过一个数组,同理,其结果为随机值,最小为0;
7.&arr[0]+1为数组第二个元素的地址,其结果为随机值,但比第1题结果小1;
(3)代码3
char arr[] = "abcdef";
1 printf("%d\n", sizeof(arr));
2 printf("%d\n", sizeof(arr+0));
3 printf("%d\n", sizeof(*arr));
4 printf("%d\n", sizeof(arr[1]));
5 printf("%d\n", sizeof(&arr));
6 printf("%d\n", sizeof(&arr+1));
7 printf("%d\n", sizeof(&arr[0]+1));
与前两题不同,这里是把字符串赋值给数组,字符串末尾会自动包含一个\0
1.arr表示整个数组,数组元素个数为7(\0也是数组的一个元素),每个元素占一个字节,故结果为7;
2..arr为数组首元素地址,地址的大小为4;
3.arr为数组首元素地址,*arr为数组首元素,大小为1;
4.arr[1]为数组第二个元素,大小为1;
5.&arr为真个数组的地址,地址大小为4;
6.&arr+1跳过整个数组,是一个地址,大小为4;
7.&arr[0]+1表示数组第二个元素的地址,大小为4;
运行结果如下:
(4)代码4
char arr[] = "abcdef";
1 printf("%d\n", strlen(arr));
2 printf("%d\n", strlen(arr+0));
3 printf("%d\n", strlen(*arr));
4 printf("%d\n", strlen(arr[1]));
5 printf("%d\n", strlen(&arr));
6 printf("%d\n", strlen(&arr+1));
7 printf("%d\n", strlen(&arr[0]+1));
1.arr是数组首元素地址(注意这里不是sizeof),故长度为6;
2.同上;
3.strlen的参数必须为地址,而*arr为数组第一个元素,代码错误;
4.同3,arr[1]为数组第二个元素,代码错误;
5.&arr为整个数组的地址,但是strlen是一个字节一个字节计算长度的,因此结果同1,长度为6;
6.&arr+1跳过整个数组(即也跳过了数组最后一个元素\0),因此长度为随机值,最小为0(一开始就遇到\0时);
7.&arr[0]+1为数组第二个元素的地址,即从第二个元素开始计算长度,结果为5;
(5)代码5
char *p = "abcdef";
1 printf("%d\n", sizeof(p));
2 printf("%d\n", sizeof(p+1));
3 printf("%d\n", sizeof(*p));
4 printf("%d\n", sizeof(p[0]));
5 printf("%d\n", sizeof(&p));
6 printf("%d\n", sizeof(&p+1));
7 printf("%d\n", sizeof(&p[0]+1));
做题之前,我们需要知道,p是一个字符指针,将一个字符串常量赋值给p,实际是将字符串的第一个元素的地址赋值给p(把常量字符串想象成数组,p可以理解为数组名【只是在有些时候当数组名,但其本质还是一个指针】)
1.p是一个指针,指针的大小为4;
2.p+1,指向数组第二个元素,是一个地址,大小为4;
3.*p是数组第一个元素,大小为1;
4.同3;
5.&p为整个数组的地址,地址的大小为4;
6.&p+1跳过整个数组,是一个地址,大小为4;
7.&p[0]+1为数组第二个元素的地址,大小为4;
运行结果如下:
(6)代码6
char *p = "abcdef";
1 printf("%d\n", strlen(p));
2 printf("%d\n", strlen(p+1));
3 printf("%d\n", strlen(*p));
4 printf("%d\n", strlen(p[0]));
5 printf("%d\n", strlen(&p));
6 printf("%d\n", strlen(&p+1));
7 printf("%d\n", strlen(&p[0]+1));
1.p指向第一个元素,故长度为6;
2.p+1指向第二个元素,故长度为5;
3.*p不是地址,故代码错误;
4.p[0]不是地址,代码错误;
5.&p取的是指针变量的地址,其类型为char**,虽然是一个地址,但是不知道指向谁,故结果为随机值;
6.&p+1同上,为随机值
7.&p[0]+1为第二个元素的地址,故长度为5;
三、二维数组
int a[3][4] = {0};
1 printf("%d\n",sizeof(a));
2 printf("%d\n",sizeof(a[0][0]));
3 printf("%d\n",sizeof(a[0]));
4 printf("%d\n",sizeof(a[0]+1));
5 printf("%d\n",sizeof(*(a[0]+1)));
6 printf("%d\n",sizeof(a+1));
7 printf("%d\n",sizeof(*(a+1)));
8 printf("%d\n",sizeof(&a[0]+1));
9 printf("%d\n",sizeof(*(&a[0]+1)));
10 printf("%d\n",sizeof(*a));
11 printf("%d\n",sizeof(a[3]));
在做题之前,我们需要知道,二维数组的首元素是第一行,即一维数组,a[x][y]中的a[x]可以当成是每一行的数组名
1.sizeof里面单独一个数组名,表示整个数组,大小为48;
2.即第一个元素的大小,为4;
3.a[0]为第一行的数组名,故这里a[0]表示第一行,大小为16;
4.a[0]表示第一行的首元素地址,故a[0]+1表示第一行第二列的元素的地址,地址的大小为4;
5.为第一行第二列的元素,大小为4;
6.a表示二维数组首元素地址,即第一行的地址,则a+1表示第二行的地址,地址的大小为4;
7.*(a+1)表示第二行,大小为16;
8.a[0]为第一行的数组名,则&a[0]+1表示第二行的地址,大小为4;
9.*(a[0]+1)表示第二行,大小为16;
10.a表示二维数组的首元素地址,即第一行的地址,则*a表示第一行,大小为16;
11.a[3]表示二维数组的第三行的数组名,这里表示第三行,大小为16;