欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > 指针与数组笔试题解析

指针与数组笔试题解析

2024/10/23 23:19:23 来源:https://blog.csdn.net/2303_79015671/article/details/140478330  浏览:    关键词:指针与数组笔试题解析

文章目录

  • 1.一维数组
    • 1.1 整型数组
    • 1.2 字符数组
  • 2. 二维数组
  • 3.指针笔试题
    • 3.1 练习1
    • 3.2 练习2
    • 3.3 练习3

数组名的意义:

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

1.一维数组

1.1 整型数组

int main()
{int a[] = {1,2,3,4};printf("%d\n",sizeof(a));//16,sizeof单独加上数组名计算的是整个数组的大小printf("%d\n",sizeof(a+0));//4或者8,这里数组名不是单独在sizeof内,所以会变成数组首元素的地址,而指针的大小根据选择的是32位还是64位而不同。printf("%d\n",sizeof(*a));//4,a是首元素的地址,被解引用后就是首元素。整型为4个字节大小printf("%d\n",sizeof(a+1));// 4/8,表示数组第二个元素的地址printf("%d\n",sizeof(a[1]));//4,表示数组第一个元素是整型printf("%d\n",sizeof(&a));// 4/8,&数组名拿到是整个数组的地址,而整个数组的地址也是指针,所以大小还是4或者8printf("%d\n",sizeof(*&a));//16,取地址和解引用相互抵消,使得本质上是sizeof(a)printf("%d\n",sizeof(&a[0]));//4/8,计算的数组首元素的地址,也就是指针printf("%d\n",sizeof(&a[0]+1));//4/8,计算的是数组第二个元素的地址,也就是指针return 0;
}
//打印结果
/*
16
8
4
8
4
8
16
8
8
*/

1.2 字符数组

#include <stdio.h>
int main()
{char arr[] = {'a','b','c','d','e','f'};printf("%d\n",sizeof(arr));printf("%d\n",sizeof(arr+1));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));return 0;//与上面解释类似
}
//打印结果:
/*
6
8
8
1
1
8
8
8
*/
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = {'a','b','c','d','e','f'};printf("%d\n",strlen(arr));//随机值,表示的是从数组的首元素开始计算直到碰到'\0'为止的长度printf("%d\n",strlen(arr+0));//随机值,表示的是从数组的首元素开始计算直到碰到'\0'为止的长度printf("%d\n",strlen(*arr));//错误写法,strlen函数参数要传地址printf("%d\n",strlen(arr[1]));//错误写法,strlen函数参数要传地址printf("%d\n",strlen(&arr));/*随机值,虽然&arr表示的是整个数组的地址,但是整个数组的地址依旧是用数组首元素的地址代表。表示的是从数组的首元素开始计算直到碰到'\0'为止的长度*/printf("%d\n",strlen(&arr+1));//随机值,表示的是从数组的最后一个元素后的地址开始计算直到碰到'\0'为止的长度。会比第一个随机值数少6个字节printf("%d\n",strlen(&arr[0]+1));//随机值,表示从数组第二个元素地址开始计算直到碰到'\0'为止的长度。会比第一个随机值数少1个字节return 0;
}
//打印结果:
/*(注释掉错误写法后)
42
42
42
36
41
*/
#include <stdio.h>
int main()
{char arr[] = "abcdef";printf("%d\n",sizeof(arr));printf("%d\n",sizeof(arr+1));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));//整体解释和第一道题类型,不过要注意的是sizeof会计算隐藏的'\0'的大小。return 0;
}
//打印结果:
/*
7
8
8
1
1
8
8
8
*/
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "abcdef";printf("%d\n",strlen(arr));//6,该数组arr最后隐藏了一个'\0',strlen计算到'\0'为止printf("%d\n",strlen(arr+0));//6,该数组arr最后隐藏了一个'\0',strlen计算到'\0'为止printf("%d\n",strlen(*arr));//错误写法,strlen函数参数要传地址printf("%d\n",strlen(arr[1]));//错误写法,strlen函数参数要传地址printf("%d\n",strlen(&arr));//6,&arr虽然表示整个数组的地址,但是地址是用数组首元素地址来代表的。printf("%d\n",strlen(&arr+1));//随机值,&arr表示整个数组的地址,+1跳过整个数组,也跳过了'\0',直到找到后面的'\0'才会停止printf("%d\n",strlen(&arr[0]+1));//5,表示从数组的第二的元素地址开始往后计算长度。	return 0;
}
//打印结果
/*(注释掉错误写法后)
6
6
6
26
5
*/
#include <stdio.h>
int main()
{char* arr = "abcdef";printf("%d\n",sizeof(arr));//4/8,这里的arr不能等同于数组,arr就是指针,这个指针指向了"abcdef"这个常量字符串printf("%d\n",sizeof(arr+1));//4/8,arr+1就表示该常量字符串第二个元素的地址printf("%d\n",sizeof(*arr));//1,对指针解引用得到的就是首元素'a',类型char大小为1字节。printf("%d\n",sizeof(arr[0]));//1,arr[0]数组首元素'a'printf("%d\n",sizeof(&arr));//4/8,&arr表示arr的地址也就是一个二级指针printf("%d\n",sizeof(&arr+1));//4/8,&arr+1也是二级指针,printf("%d\n",sizeof(&arr[0]+1));//4/8,表示第二个元素'b'的地址return 0;
}
//打印结果:
/*
8
8
1
1
8
8
8
*/
#include <stdio.h>
#include <string.h>
int main()
{char* arr = "abcdef";printf("%d\n",strlen(arr));//6,arr存放的就是首元素的地址printf("%d\n",strlen(arr+1));//5,传入第二个元素的地址printf("%d\n",strlen(*arr));//错误写法,strlne必须传地址进去printf("%d\n",strlen(arr[0]));//错误写法,strlne必须传地址进去printf("%d\n",strlen(&arr));//随机值,&arr是首元素'a'地址的地址,是一个二级指针,会一直找到下一个'\0'为止。printf("%d\n",strlen(&arr+1));//随机值,是一个二级指针(不一定在&arr后面),会一直找到下一个'\0'为止。printf("%d\n",strlen(&arr[0]+1));//5,传入第二个元素的地址return 0;
}
//打印结果:
/*(注释掉错误写法后)
6
5
3
11
5
*/

2. 二维数组

#include <stdio.h>
int main()
{int a[3][4] = {0};printf("%d\n",sizeof(a));//48,sizeof(数组名)计算的整个数组的大小printf("%d\n",sizeof(a[0][0]));//4,a[0][0]就是首元素printf("%d\n",sizeof(a[0]));//16,a[0]是第一行这个一维数组的数组名//数组名算是单独放在sizeof内部了,计算的是整个数组的大小,大小是16个字节printf("%d\n",sizeof(a[0]+1));//4/8,a[0]是第一行数组名,+1就不算单独放到sizeof中了。printf("%d\n",sizeof(*(a[0]+1)));//4,相当于a[0][1],拿到了数组第1行第2列的元素printf("%d\n",sizeof(a+1));// 4/8,数组名除俩个的特殊情况外都是数组首元素的地址,//这里加1拿到就是第二行的地址,是指针printf("%d\n",sizeof(*(a+1)));//16,相当于a[1],计算的第二行的大小printf("%d\n",sizeof(&a[0]+1));//4/8,&a[0]+1,a[0]相当于第一行的数组名,&a[0]就是第一行数组的地址,加1跳过第一行,就是第二行数组的地址,是指针。printf("%d\n",sizeof(*(&a[0]+1)));//16,计算的是第二行的大小,&a[0]拿到第一行的地址,然后+1拿到第2行的地址,再解引用拿到就是第二行了。printf("%d\n",sizeof(*a));//16,a表示的一行的地址,*a就是拿到第一行,printf("%d\n",sizeof(a[3]));//16,虽然数组越界了但是,在sizeof的执行过程中是不会使用a[3]的,sizof(a[3])会把a[3]理解为第4行的数组名,return 0;
}
//打印结果:
/*
48
4
16
8
4
8
16
8
16
16
16
*/

3.指针笔试题

3.1 练习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;
}
//打印结果:2,5
/*
解释:&a拿到的是整个数组的地址,加1后跳过整个数组来到数组最后一个元素后面。也就说明了ptr的指向的地址再5的地址的后面,然后强制类型转换成整型指针,而整型指针-1只会前移动4个字节,ptr会指向5的地址。而a是数组名,表示数组首元素的地址,+1后就来到了第二个元素的地址。
*/

指针的指向

3.2 练习2

#include <stdio.h>
//这个结构体的大小是20个字节
struct test
{int Num;char* pcname;short sdata;char cha[2];short sba[4];
}*p = (struct Test*)0x100000;
//假设p的值为0x100000.
//已知test结构体的大小是20个字节
int main()
{printf("%p\n",p+0x1);printf("%p\n",(unsigned long)p+0x1);printf("%p\n",(unsigned long*)p+0x1);return 0;
}
//打印结果:
/*
00100014
00100001
00100004
*/
/*
解释:这里p指向的地址是0x100000。0x1就是1的16进制表达。p加1,因为p指向类型是struct test,类型大小20个字节,加1后也会跳过20这个字节(转换成16进制就是14).
后面p指针被强制类型转换成了一个无符号长整形的变量,这个类型不是指针变量,加1就是整数加1.
最后一个强制类型转换成了一个无符号长整形指针变量,是指针,然后无符号长整形的大小是4个字节,加1也就是跳过4个字节。
*/

3.3 练习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);//%x为16进制打印return 0;
}
//打印结果:4,2000000
/*
解释放下面
*/

ptr1:&a+1表示的跳过这个数组后的地址,也就是4后面的地址,然后被强制类型转换为了int*
ptr2:a是数组首元素的地址,都是被强制类型转换为了整型,然后+1,因为是整型加1就是数字加1.然后又被强制类型转换成了int*。
此时的指向如图所示
指针的指向
因为元素在系统当中是小端存储的,
1会被存储为:01 00 00 00
此时ptr2指向的就是01后面00的位置。
我们又知道数组中1的后面是2。
小端存储就是 01 00 00 00 02 00 00 00
ptr2被强制类型转换为了int*,解引用会一次取出4个字节,取出的就是00 00 00 02,将顺序反转成正常顺序就是02000000,打印时省略掉了第一个0变成了200000
ptr1[-1]的意思就是*(prt1-1).就拿出来4.

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com