C语言数组和指针笔试题小结

C语言数组和指针笔试题小结

一维数组

	int a[] = {1,2,3,4};
	printf("%d\n", sizeof(a));  // 16,sizeof(数组名),当数组名单独放在sizeof()中时,数组名表示整个数组
	printf("%d\n", sizeof(a+0));  // 8,数组名没有单独存放时表示首元素地址
	printf("%d\n", sizeof(*a));  // 4
	printf("%d\n", sizeof(a+1));  // 8
	printf("%d\n", sizeof(a[1]));  // 4
	printf("%d\n", sizeof(&a));  // 8
	printf("%d\n", sizeof(*&a));  // 16
	printf("%d\n", sizeof(&a+1));  // 8
	printf("%d\n", sizeof(&a[0]));  // 8
	printf("%d\n", sizeof(&a[0]+1));  // 8

字符数组

	char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
	printf("%d\n", sizeof(arr));  // 6
	printf("%d\n", sizeof(arr+0));  // 8
	printf("%d\n", sizeof(*arr));  // 1
	printf("%d\n", sizeof(arr[1]));  // 1
	printf("%d\n", sizeof(&arr));  // 8
	printf("%d\n", sizeof(&arr+1));  // 8
	printf("%d\n", sizeof(&arr[0]+1));  // 8
	
	printf("%d\n", strlen(arr));  // 随机值,strlen()在'\0'处停止,此时无法判断'f'后面是不是'\0'
	printf("%d\n", strlen(arr+0));  // 随机值
	printf("%d\n", strlen(*arr));  
	// err,strlen()传入的应该是一个地址,此时传入的是'a',会将ASCII码值97当作地址,访问内存出错
	printf("%d\n", strlen(arr[1]));  // err
	printf("%d\n", strlen(&arr));  // 随机值
	printf("%d\n", strlen(&arr+1));  // 随机值-6
	printf("%d\n", strlen(&arr[0]+1));  // 随机值-1
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));  // 7
	printf("%d\n", sizeof(arr+0));  // 8
	printf("%d\n", sizeof(*arr));  // 1
	printf("%d\n", sizeof(arr[1]));  // 1
	printf("%d\n", sizeof(&arr));  // 8
	printf("%d\n", sizeof(&arr+1));  // 8
	printf("%d\n", sizeof(&arr[0]+1));  // 8 
	
	printf("%d\n", strlen(arr));  // 6
	printf("%d\n", strlen(arr+0));  // 6
	printf("%d\n", strlen(*arr));  // err
	printf("%d\n", strlen(arr[1]));  // err
	printf("%d\n", strlen(&arr));  // 6
	printf("%d\n", strlen(&arr+1));  // 随机值
	printf("%d\n", strlen(&arr[0]+1));  // 5
	char *p = "abcdef";
	printf("%d\n", sizeof(p));  // 8
	printf("%d\n", sizeof(p+1));  // 8
	printf("%d\n", sizeof(*p));  // 1
	printf("%d\n", sizeof(p[0]));  // 1
	printf("%d\n", sizeof(&p));  // 8
	printf("%d\n", sizeof(&p+1));  // 8
	printf("%d\n", sizeof(&p[0]+1));  // 8
	
	printf("%d\n", strlen(p));  // 6
	printf("%d\n", strlen(p+1));  // 5
	printf("%d\n", strlen(*p));  // err
	printf("%d\n", strlen(p[0]));  // err
	printf("%d\n", strlen(&p));  // 随机值x
	printf("%d\n", strlen(&p+1));  // 随机值y
	printf("%d\n", strlen(&p[0]+1));  // 5

二维数组

	int a[3][4] = {0};
	printf("%d\n", sizeof(a));  // 48
	printf("%d\n", sizeof(a[0][0]));  // 4
	printf("%d\n", sizeof(a[0]));  // 16, a[0]是第一行数组名,数组名单独放在sizeof()中表示整个数组的大小
	printf("%d\n", sizeof(a[0]+1));  // 8, a[0]没有单独放在sizeof()中,所以表示第一行首元素地址,a[0]+1表示第一行第二个元素地址
	printf("%d\n", sizeof(*(a[0]+1)));  // 4
	printf("%d\n", sizeof(a+1));  
	// 8,a没有单独放在sizeof()中,表示数组首元素地址,对于二维数组,首元素地址相当于第一行地址,这里是第二行地址。
	printf("%d\n", sizeof(*(a+1)));  // 16
	printf("%d\n", sizeof(&a[0]+1));  // 8,数组名取地址是数组的地址,这里表示第二行的地址
	printf("%d\n", sizeof(*(&a[0]+1)));  // 16
	printf("%d\n", sizeof(*a));  // 16
	printf("%d\n", sizeof(a[3]));  
	// 16,虽然第四行不存在,但sizeof()不会访问标识的空间,内部的表达式不参与运算,所以a[3]没有去访问第四行,只是通过类型进行推断

数组名的意义:
1、sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小;
2、&数组名,这里的数组名表示整个数组,取出的是整个数组的地址;
3、除此之外所有的数组名都表示首元素的地址。

指针

// 第一题
	int a[5] = {1,2,3,4,5};
	int *ptr = (int *)(&a + 1);
	printf("%d,%d", *(a+1), *(ptr-1));
// 打印结果为 2,5
// &a + 1 越过的是整个数组的大小,强制类型转换为 int*,其向前一个int大小,指向a[4]的地址
// a + 1 越过的是一个int的大小,a指向数组首元素地址,+1操作后指向a[1]的位置
// 第二题
	struct Test
	{
		int Num;
		char* pcName;
		short sDate;
		char cha[2];
		short sBa[4];
	}*p;
// 假设P的值为0x100000,如下的表达式的值为多少?
// 整数要赋值给p结构体指针,需要进行强制类型转换 *p = (struct Test*)0x100000
// p + 0x1 = 0x____?   100018
// (unsigned long)p + 0x1 = 0x____?   100001
// (unsigned int*)p + 0x1 = 0x____?   100004
// 第三题
	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;
	}
// ptr1[-1]即 *(ptr1 + (-1))
// 注意大端小端数据存储强调的是数字放到内存中字节的顺序
// 打印结果为:0x00000004 0x02000000
// 第四题
	int main()
	{
		int a[3][2] = {(0,1), (2,3), (4,5)};
		int *p;
		p = a[0];
		printf("%d\n", p[0]);
	} 
// 打印结果为1
// 数组初试化的过程中,如果是a[3][2] = {{0,1}, {2,3}, {4,5}};那么数组中按顺序存放的将是012345
// 但此时初试化时,数据使用小括号括起来,存放的是由括号括起来的逗号表达式
// 逗号表达式的结果为从左向右计算,取最后一个表达式的结果,所以数组的前三项存放的是 1,3,5,后续补零
// 第五题
	int main()
	{
		int a[5][5];
		int (*p) [4];
		p = a; 
		// printf("a_ptr=%#p,p_ptr=%#p\n", &a[4][2], &p[4][2]);
		printf("%p,%d\n", &p[4][2]-&a[4][2], &p[4][2]-&a[4][2]);
	
		return 0;
	}
// 第一行%#p表示带格式打印地址,即加上 0x 前缀
// 第二行打印结果为 FFFFFFFC -4
// 第六题
	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;
	}
// 打印结果为 10,5
// 第七题
	int main()
	{
		char *a[] = {"work", "at", "alibaba"};
		char **pa = a;
		pa++;
		printf("%s\n", *pa);
		
		return 0;
	}
// 打印结果为 at
// a[]数组是一个指针数组,存放的是 char*类型的指针,分别指向三个字符串首字符地址
// 第八题
	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;
	}
// 打印结果为:POINT、ER、ST、EW
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页