概要
理解和使用指针,学会指针的是运算逻辑;知道数组名的作用;
本电脑为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()接受的也是地址,计算字符串长度;