指针的理解及面试题

概要

理解和使用指针,学会指针的是运算逻辑;知道数组名的作用;

本电脑为64位系统。

整体架构流程

通过strlen和sizeof等运算,学会指针的运算,并懂得计算机运算逻辑。

名词解释

sizeof(数组名),计算数据所占几个字节,数组名代表数组的首元素地址,输出为int类型

strlen(数组名),计算数组的长的,数组名代表数组的首元素地址,输出为int类型

使用strlen需要引用"string.h"头文件

数组

int main()
{
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//16
	printf("%d\n", sizeof(a + 0));//a代表首元素地址,a+0还是首元素地址,一个地址大小为4/8
	printf("%d\n", sizeof(*a));//a代表首元素地址,解引用为首元素大小,大小为4
	printf("%d\n", sizeof(int));//sizeof计算的是类型大小
	printf("%d\n", sizeof(a + 1));//a代表首元素地址,a+1为第二个元素地址大小,大小为4/8
	printf("%d\n", sizeof(a[1]));//第二个元素大小4个字节
	printf("%d\n", sizeof(&a));//&a是一个地址,大小为4/8
	printf("%d\n", sizeof(*&a));//16,先取地址a,然后解引用,是整个数组
	printf("%d\n", sizeof(&a + 1));//取出数组地址,在+1跳过整个数组后的地址,还是地址,4/8
	printf("%d\n", sizeof(&a[0]));//首元素地址4/8
	printf("%d\n", sizeof(&a[0] + 1));//首元素地址再+1,就是第二元素地址 
    return 0;
}

int a[]={1,2,3,4}在代表的是4个int类型的数。

1  . sizeof(a)是计算数组a站几个字节,a代表首元素地址,sizeof计算的是类型大小,a类型为数组,是数组类型大小为元素类型乘以元素个数

2 . 代表首元素地址,a+0还是首元素地址,一个地址大小为4/8

3 . a代表首元素地址,解引用为首元素1,首元素1为int 类型 ,int 大小为4

4.sizeof计算的是类型大小

5. a为首元素地址,a+1为第二个元素地址,一个地址的大小为4/8个字节(地址在大小在不同的大小也有所不同,32位平台上位4个字节,在64位平台上位8个直接)。

6. a[1]为第二个元素即为2,2为int类型,int类型大小为4;

7 .&a为一个地址,a为首元素地址,在取地址为首元素地址的地址,一个地址的大小为4/8;

8. *&a 先取出a的地址,然后解引用a地址处的数组a,即和1一样;

9. &a[0]为取出首元素的地址,一个地址的大小为4/8;

10. &a[0] + 1取出首元素的地址然后再在这个地址上加以为第二个元素地址


总结:1.sizeof(数组名),这里数组名表示整个数组大小,单位为字节
2 . &数组名,这里表示整个数组,取出的是整个数组的地址


字符数组

int main()
{
// sizeof(类型),只需要类型就可以,根据类型计算大小
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//6.数组名单独放在sizeof中,是地址,计算的是arr[6],所以大小为6
	printf("%d\n", sizeof(arr + 0));//类型为char* ,arr+0表示第一个元素地址大小为4/8
	printf("%d\n", sizeof(*arr));//*arr为数组首元素大小是一个字节
	printf("%d\n", sizeof(arr[1]));//为数组第二个元素为1
	printf("%d\n", sizeof(&arr));//&arr取的是数组的地址,4/8
	printf("%d\n", sizeof(&arr + 1));//取地址arr是数组地址,加1是跳过整个数组地址4/8
	printf("%d\n", sizeof(&arr[0] + 1));//&arr[0]是第一个元素地址,+1是第二元素地址4/8
	printf("%d\n", strlen(arr));//随机值,统计的是\0前面的元素个数,arr中没有\0
	printf("%d\n", strlen(arr + 0));//是随机值,arr+0是首元素地址,统计的是\0前面的元素个数,arr中没有\0
	printf("%d\n", strlen(*arr));//strlen需要的是地址,*arr是首元素a==97(ASCII),找的是地址为97的地址
	printf("%d\n", strlen(arr[1])); //strlen需要的是地址,* arr是首元素a == 98(ASCII),找的是地址为98的地址
	printf("%d\n", strlen(&arr));//&arr和首元素地址的值是一样的,随机值,统计的是\0前面的元素个数,arr中没有\0
	printf("%d\n", strlen(&arr + 1));//&arr和首元素地址的值是一样的,随机值,跳过这个数组计算
//&arr是//随机值,统计的是\0前面的元素个数,arr中没有\0,&arr+1是跳过arr这个数组后面的地址,若二者做差可计算数组元素个数
	printf("%d\n", strlen(&arr[0] + 1));//是第二个元素地址,是随机值
    return 0;
}

sizeof(类型),只需要类型就可以,根据类型计算大小;

数组名的理解:

int arr[3]={1,2,3};
int* p=arr;//类型匹配,arr是首元素地址,数组名做右值代表首元素地址
int*pp=&arr;//不匹配,&arr是取出整个数组的地址,类型为int (*)[3],也就是数组指针,应给用数组指针来接受;

总结

1.当数组名放在右边时,意义是普通指针int* (char*)等类型,指针指向的是数组中每个元素

2.当&数组名时,取出的是数组整个地址,类型为int (*)[]类型,是数组指针,指针一次性指向的是数组全部或几个(由[]里面的数字来决定);如图为指针数组

字符串数组

	char arr1[] = "abcdef";//带有\0
	printf("%d\n", sizeof(arr1));//7  计算带上\0
	printf("%d\n", sizeof(arr1 + 0));//8
	printf("%d\n", sizeof(*arr1));//1
	printf("%d\n", sizeof(arr1[1]));//1
	printf("%d\n", sizeof(&arr1));//4/8
	printf("%d\n", sizeof(&arr1 + 1));//4/8
	printf("%d\n", sizeof(&arr1[0] + 1));//4/8
	printf("%d\n", strlen(arr1));//6
	printf("%d\n", strlen(arr1 + 0));//6
	printf("%d\n", strlen(*arr1));//strlen需要的是地址,*arr是首元素a==97(ASCII),找的是地址为97的地址
	printf("%d\n", strlen(arr1[1]));// strlen需要的是地址,* arr是首元素a == 98(ASCII),找的是地址为98的地址
	printf("%d\n", strlen(&arr1));//6
	printf("%d\n", strlen(&arr1 + 1));//随机值,&arr是一个地址,地址加1,
	printf("%d\n", strlen(&arr1[0] + 1));//5

字符串在数组中存储在后面有\0结束字符

字符串数组

	//二维数组
	int a[3][4] = { 0 };
	//0 0 0 0
	//0 0 0 0
	//0 0 0 0
	printf("%d\n", sizeof(a));//12*4
	printf("%d\n", sizeof(a[0][0]));//4
	printf("%d\n", sizeof(a[0]));//4*4//的一行地址处的大小,计算的整个一维数组的大小
	printf("%d\n", sizeof(a[0] + 1));//4/8
	//a[0]首元素地址,也是第一行的地址,类型为int(*) [4],+1就是*((*)[4]+1),是一个地址
	//a[0]是首元素地址,也就是a[0][0]的地址,a[0]+1就是a[0][1]第一行的二个元素的地址,地址是4/8
	printf("%d\n", sizeof(*(a[0] + 1)));//4
	printf("%d\n", sizeof(a + 1));//a是首元素地址,是第一行地址,a+1是第二行地址,大小为4/8
	printf("%d\n", sizeof(*(a + 1)));//16
	printf("%d\n", sizeof(&a[0] + 1));//&a[0]是第一行地址,+1是第二行地址
	printf("%d\n", sizeof(*(&a[0] + 1)));//16 
	printf("%d\n", sizeof(*a));//第一行大小,16
	printf("%d\n", sizeof(a[3]));//16//类型为int (*)[4]
	//sizeof(元素类型),只关心元素类型
 p[0]——>*(p+0)

在二维数组中,第一个方块可以省略,代表行,第二个方块不可以省略,代表列;

指针中的*号和[]有等价的意思;

机器在运算的过程中,是将[]转化为*来进行指针运算;

p[2]——>*(p+2);



小结

1  &数组名、数组名和数组名[]意义是不同的;

2  sizeof(数组名),这里数组名表示整个数组大小,单位为字节;sizeof()接受的是一个地址

3  strlen()接受的也是地址,计算字符串长度;

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃喵的鲤鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值