1指针和数组笔试题解析
一维数组
说出下面代码的输出结果
//一维数组 #include<stdio.h> int main() { int a[] = { 1,2,3,4 }; printf("%d\n", sizeof(a)); printf("%d\n", sizeof(a + 0)); printf("%d\n", sizeof(*a)); printf("%d\n", sizeof(a + 1)); printf("%d\n", sizeof(a[1])); printf("%d\n", sizeof(&a)); printf("%d\n", sizeof(*&a)); printf("%d\n", sizeof(&a + 1)); printf("%d\n", sizeof(&a[0])); printf("%d\n", sizeof(&a[0] + 1)); return 0; }
解析:
//一维数组 //数组名的意义: //1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。 //2. & 数组名,这里的数组名表示整个数组,取出的是整个数组的地址。 //3. 除此之外所有的数组名都表示首元素的地址。 #include<stdio.h> int main() { int a[] = { 1,2,3,4 }; printf("%d\n", sizeof(a));//16 printf("%d\n", sizeof(a + 0));//4/8 第一个元素的地址 printf("%d\n", sizeof(*a));//4 第一个元素的大小 printf("%d\n", sizeof(a + 1));//4/8 第二个元素的地址 printf("%d\n", sizeof(a[1]));//4 第二个元素的大小 printf("%d\n", sizeof(&a));//4/8 整个数组的地址 printf("%d\n", sizeof(*&a));//16 整个数组的大小(取地址解引用相当于最上面的printf) printf("%d\n", sizeof(&a + 1));//4/8 跳过a数组的下个空间的地址 printf("%d\n", sizeof(&a[0]));//4/8 第一个元素的地址 printf("%d\n", sizeof(&a[0] + 1));//4/8 第二个元素的地址 return 0; }
字符数组
说出下面代码的输出结果
#include<stdio.h> #include<string.h> int main() { char arr[] = { 'a','b','c','d','e','f' }; printf("%d\n", sizeof(arr)); printf("%d\n", sizeof(arr + 0)); printf("%d\n", sizeof(*arr)); printf("%d\n", sizeof(arr[1])); printf("%d\n", sizeof(&arr)); printf("%d\n", sizeof(&arr + 1)); printf("%d\n", sizeof(&arr[0] + 1)); printf("%d\n", strlen(arr)); printf("%d\n", strlen(arr + 0)); printf("%d\n", strlen(*arr)); 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[] = { 'a','b','c','d','e','f' }; printf("%d\n", sizeof(arr));//6 printf("%d\n", sizeof(arr + 0));//4/8 第一个元素的地址 printf("%d\n", sizeof(*arr));//1 第一个元素的大小 printf("%d\n", sizeof(arr[1]));//1 printf("%d\n", sizeof(&arr));//4/8 printf("%d\n", sizeof(&arr + 1));//4/8 printf("%d\n", sizeof(&arr[0] + 1));//4/8 printf("%d\n", strlen(arr));//随机数(没有\0) printf("%d\n", strlen(arr + 0));//上面的随机数(没有\0) printf("%d\n", strlen(*arr));//(把97当做地址)错误 printf("%d\n", strlen(arr[1]));//错误 printf("%d\n", strlen(&arr));//上面的随机数(没有\0) printf("%d\n", strlen(&arr + 1));//上面的随机数-6(没有\0) printf("%d\n", strlen(&arr[0] + 1));//上面的随机数-1(没有\0) return 0; }
说出下面代码的输出结果
#include<stdio.h> #include<string.h> int main() { char arr[] = "abcdef"; printf("%d\n", sizeof(arr)); printf("%d\n", sizeof(arr + 0)); printf("%d\n", sizeof(*arr)); printf("%d\n", sizeof(arr[1])); printf("%d\n", sizeof(&arr)); printf("%d\n", sizeof(&arr + 1)); printf("%d\n", sizeof(&arr[0] + 1)); printf("%d\n", strlen(arr)); printf("%d\n", strlen(arr + 0)); printf("%d\n", strlen(*arr)); 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"; printf("%d\n", sizeof(arr));//7 (加上\0)!!! printf("%d\n", sizeof(arr + 0));//4/8 printf("%d\n", sizeof(*arr));//1 printf("%d\n", sizeof(arr[1]));//1 printf("%d\n", sizeof(&arr));//4/8 printf("%d\n", sizeof(&arr + 1));//4/8 printf("%d\n", sizeof(&arr[0] + 1));//4/8 printf("%d\n", strlen(arr));//6 printf("%d\n", strlen(arr + 0));//6 printf("%d\n", strlen(*arr));//错误emm printf("%d\n", strlen(arr[1]));//错误emm printf("%d\n", strlen(&arr));//6 printf("%d\n", strlen(&arr + 1));//随机数 printf("%d\n", strlen(&arr[0] + 1));//5 return 0; }
说出下面代码的输出结果
#include<stdio.h> #include<string.h> int main() { char* p = "abcdef"; printf("%d\n", sizeof(p)); printf("%d\n", sizeof(p + 1)); printf("%d\n", sizeof(*p)); printf("%d\n", sizeof(p[0])); printf("%d\n", sizeof(&p)); printf("%d\n", sizeof(&p + 1)); printf("%d\n", sizeof(&p[0] + 1)); printf("%d\n", strlen(p)); printf("%d\n", strlen(p + 1)); printf("%d\n", strlen(*p)); printf("%d\n", strlen(p[0])); printf("%d\n", strlen(&p)); printf("%d\n", strlen(&p + 1)); printf("%d\n", strlen(&p[0] + 1)); return 0; }
解析:
#include<stdio.h> #include<string.h> int main() { char* p = "abcdef"; printf("%d\n", sizeof(p));//4/8 指针的大小 printf("%d\n", sizeof(p + 1));//4/8 第二个元素的地址! printf("%d\n", sizeof(*p));//1 第一个元素的大小! printf("%d\n", sizeof(p[0]));//1 同上emm printf("%d\n", sizeof(&p));//4/8 printf("%d\n", sizeof(&p + 1));//4/8 printf("%d\n", sizeof(&p[0] + 1));//4/8 printf("%d\n", strlen(p));//6 printf("%d\n", strlen(p + 1));//5 printf("%d\n", strlen(*p));//错误 printf("%d\n", strlen(p[0]));//错误 printf("%d\n", strlen(&p));//随机数 从p的地址算,p里面存的地址!! printf("%d\n", strlen(&p + 1));//和上面不同的随机数 printf("%d\n", strlen(&p[0] + 1));//5 return 0; }
二维数组
说出下面代码的输出结果
#include<stdio.h> int main() { int a[3][4] = { 0 }; printf("%d\n", sizeof(a)); printf("%d\n", sizeof(a[0][0])); printf("%d\n", sizeof(a[0])); printf("%d\n", sizeof(a[0] + 1)); printf("%d\n", sizeof(*(a[0] + 1))); printf("%d\n", sizeof(a + 1)); printf("%d\n", sizeof(*(a + 1))); printf("%d\n", sizeof(&a[0] + 1)); printf("%d\n", sizeof(*(&a[0] + 1))); printf("%d\n", sizeof(*a)); printf("%d\n", sizeof(a[3])); return 0; }
解析:
#include<stdio.h> int main() { int a[3][4] = { 0 }; printf("%d\n", sizeof(a));//12*4=48 整个数组大小 printf("%d\n", sizeof(a[0][0]));//4 第一个元素大小 printf("%d\n", sizeof(a[0]));//16 下一a[0]不是单独放在内部,不表示第一行 printf("%d\n", sizeof(a[0] + 1));//4/8 a[0]是整形的地址,+1跳过一个整形emm printf("%d\n", sizeof(*(a[0] + 1)));//4 第一行第二个元素的大小 printf("%d\n", sizeof(a + 1));//4/8 第二行的地址 printf("%d\n", sizeof(*(a + 1)));//16 第二行大小 相当于a[1] printf("%d\n", sizeof(&a[0] + 1));//4/8 第二行地址 printf("%d\n", sizeof(*(&a[0] + 1)));//16 第二行大小 同上上 printf("%d\n", sizeof(*a));//16 第一行大小等价于*(a+0)等价于a[0] printf("%d\n", sizeof(a[3]));//16 3+5 1.值属性:8 2.类型属性:int //a[3] 值属性越界了,但是类型属性是int [4] 编译器推算的,不会真正取地址emm //且sizeof内部是不进行计算的 return 0; }
总结:
数组名的意义:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。
2指针笔试题一
笔试题1:
#include<stdio.h> int main() { int a[5] = { 1, 2, 3, 4, 5 }; int *ptr = (int *)(&a + 1); printf( "%d,%d", *(a + 1), *(ptr - 1)); return 0; } //程序的结果是什么?
解析:
#include<stdio.h> int main() { int a[5] = { 1, 2, 3, 4, 5 }; int* ptr = (int*)(&a + 1); //整个数组地址+1跳过一个数组 本来的类型是int*[5] printf("%d,%d", *(a + 1), *(ptr - 1));//2,5 都是整形指针,只能跳过4个字节emm return 0; }
笔试题2:
#include<stdio.h> //由于还没学习结构体,这里告知结构体的大小是20个字节 struct Test { int Num; char* pcName; short sDate; char cha[2]; short sBa[4]; }*p; //假设p 的值为0x100000。 如下表表达式的值分别为多少? //已知,结构体Test类型的变量大小是20个字节 int main() { printf("%p\n", p + 0x1); printf("%p\n", (unsigned long)p + 0x1); printf("%p\n", (unsigned int*)p + 0x1); return 0; }
解析:
#include<stdio.h> //由于还没学习结构体,这里告知结构体的大小是20个字节 struct Test { int Num; char* pcName; short sDate; char cha[2]; short sBa[4]; }*p; //假设p 的值为0x100000。 如下表表达式的值分别为多少? //已知,结构体Test类型的变量大小是20个字节 int main() { printf("%p\n", p + 0x1);//+16进制的1,就是1 这个结构体指针+1跳过20字节 //0x100000变成0x100014 (16进制14就是10进制的20) printf("%p\n", (unsigned long)p + 0x1); //整形+1就是+1 0x100001 printf("%p\n", (unsigned int*)p + 0x1);//跳过4个字节 0x100004 return 0; }
笔试题3:
#include<stdio.h> 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; }
解析:
#include<stdio.h> int main() { int a[4] = { 1, 2, 3, 4 }; int* ptr1 = (int*)(&a + 1); //跳过一个数组 int* ptr2 = (int*)((int)a + 1); //a的地址转化为int +1 //一个地址给一个字节,差一个字节 printf("%x,%x", ptr1[-1], *ptr2); //ptrl[-1]==*(ptr1-1)==4 return 0; } //结果是4,2000000 看图
看看佬的讲解:
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)(中):https://developer.aliyun.com/article/1513063