💕"痛苦难以避免,而磨难可以选择。"-->村上春树💕
作者:Mylvzi
文章主要内容:数据在内存中的存储
核心知识点:
核心:
1.对于数组名的理解:数组名是数组首元素的地址(二维数组的数组名就是第一行的地址),但有两个例外,一是单独出现在sizeof内部,表示整个数组的大小,二是&数组名,代表存放整个数组的地址;
2.理解sizeof只关注()的数组类型,是地址,大小就为4/8;关注()的数据类型(数组的数据类型就是去掉数组名)
3.理解指针变量存储字符串的本质-->存储字符串首元素的地址
4.理解二维数组的元素构成,即二维数组是一维数组的数组;
5.理解数组与指针之间的的等价关系;arr[1]-->*(arr+1) *arr-->*(arr+0)-->arr[0]
6.理解strlen函数的本质即参数类型,本质是计算\0之前的字符个数,参数是const char*,是一个地址,也就是说strlen是从你传的地址作为首地址,一直向后读取字符个数,直到遇到\0;当()是元素时,会从其对应的ascii码值所在的地址访问,造成非法访问,报错
相关代码代码如下:
int main() { /*一维数组*/ //数组名代表数组首元素地址,但有两个例外 //1.sizeof数组名,计算的是整个数组的大小(数组名单独放在sizeof内部) //2.&数组名,代表整个数组的地址 //sizeof 只关注类型,要分清代表的是元素还是地址 //对于指针,我们要关注他的指向,也就是存放的地址;其大小是固定的 int a[] = { 1,2,3,4 }; printf("%d\n", sizeof(a));//16 ->int [4] printf("%d\n", sizeof(a + 0));//这里的a是数组首元素的地址,+0还是数组首元素的地址,大小为4/8byte printf("%d\n", sizeof(*a));//数组首元素,是元素,4(int类型) printf("%d\n", sizeof(a + 1));//第二个元素的地址,是地址,大小为4/8byte printf("%d\n", sizeof(a[1]));//第二个元素,是元素,大小为4 printf("%d\n", sizeof(&a));//&a也是地址,是地址,4/8byte printf("%d\n", sizeof(*&a));//16 等价于sizeof(a) //&a 是数组的地址,是一个数组指针变量,类型为int(*)[4],解引用就是访问4个int类型的元素 printf("%d\n", sizeof(&a + 1));//地址,大小为4/8byte printf("%d\n", sizeof(&a[0]));//地址,大小为4/8byte printf("%d\n", sizeof(&a[0] + 1));//地址,大小为4/8byte /*字符数组*/ /*char arr[] = { 'a','b','c','d','e','f' };*/ printf("%d\n", sizeof(arr));//数组名在sizeof内部,计算整个数组的大小,6 printf("%d\n", sizeof(arr + 0));//是地址,大小为4/8 printf("%d\n", sizeof(*arr));//代表字符a,大小为1 printf("%d\n", sizeof(arr[1]));//代表字符b,大小为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 //strlen的参数是const char* ,计算的是\0之前的字符个数 printf("%d\n", strlen(arr));//随机值 printf("%d\n", strlen(arr + 0));//随机值 printf("%d\n", strlen(*arr));//err strlen的参数是一个指针,是地址,*arr,相当于将a的地址传了过去,以97为起始地址,属于非法访问内存 printf("%d\n", strlen(arr[1]));//err 同上 printf("%d\n", strlen(&arr));//随机值 &arr的值和arr的值是一样的,都指向数组首元素地址 printf("%d\n", strlen(&arr + 1));//随机值 数组最后一个元素的下一位的地址 printf("%d\n", strlen(&arr[0] + 1));//随机值 从数组第二个元素开始打印字符串 //sizeof只关注类型,传arr是数组,数组的类型是去掉数组名 // 对于sizeof来说,只需注意他是地址还是普通元素 char arr[] = "abcdef"; //a b c d e f \0 printf("%d\n", sizeof(arr));//数组类型:char [7]; -->7 printf("%d\n", sizeof(arr + 0));//4 地址 printf("%d\n", sizeof(*arr));//1 printf("%d\n", sizeof(arr[1]));//1 printf("%d\n", sizeof(&arr));//4 本质是一个地址 printf("%d\n", sizeof(&arr + 1));//4 地址 printf("%d\n", sizeof(&arr[0] + 1));//4 地址 printf("%d\n", strlen(arr));//6 printf("%d\n", strlen(arr + 0));//6 printf("%d\n", strlen(*arr));//非法访问内存 printf("%d\n", strlen(arr[1]));//同上 printf("%d\n", strlen(&arr));//6 printf("%d\n", strlen(&arr + 1));//随机值 printf("%d\n", strlen(&arr[0] + 1));//5 //利用字符指针存储字符串-->指针内存储的是字符串首字符的地址 const char* p = "abcdef"; printf("%d\n", sizeof(p));//4 地址 printf("%d\n", sizeof(p + 1));//4 地址 printf("%d\n", sizeof(*p));//1 元素 printf("%d\n", sizeof(p[0]));//p[0]->*(p+0)->*p 1 printf("%d\n", sizeof(&p));//&p->char** 4 printf("%d\n", sizeof(&p + 1));//&p,char**,+1,注意此处的指针变量与数组无关 //存储的是P本身的地址 4 printf("%d\n", sizeof(&p[0] + 1));//4 -->b的地址 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));//随机值 printf("%d\n", strlen(&p + 1));//随机值 printf("%d\n", strlen(&p[0] + 1));//5 /*二维数组*/ //学会数组中的等价关系 // 给定arr是数组名(一维,二维皆可) //arr[1]-->*(arr+1) int a[3][4] = { 0 }; printf("%d\n", sizeof(a));//计算整个数组的大小,3*4*4 48 printf("%d\n", sizeof(a[0][0]));//4 printf("%d\n", sizeof(a[0]));//4*4=16 a[0]是一个一维数组的地址,类型为int(*)[4] //a[0]是第一行一维数组的数组名,单独出现在sizeof内部,计算整个一维数组的大小 printf("%d\n", sizeof(a[0] + 1));//4 a[0]是第一行一维数组的数组名,没有单独出现在sizeof内部 //所以代表第一行一维数组的首元素的地址-->a[0][0] //a[0][0]+1 就是a[0][1]的地址,是一个指针变量;一定要注意指针指向 printf("%d\n", sizeof(*(a[0] + 1)));//4 计算的就是第一行第二个元素的大小 printf("%d\n", sizeof(a + 1));//4 //a是二维数组名,是第一行的地址,存的时候是通过数组指针存放的int(*)[4] //a+1是第二行的地址,是一个指针变量 printf("%d\n", sizeof(*(a + 1)));//16 //*(a+1)-->a[1] sizeof(*(a+1))-->sizeof(a[1]) int[4] printf("%d\n", sizeof(&a[0] + 1));//4 是第二行一维数组的地址,本质是一个地址 //&a[0]是第一行的地址 printf("%d\n", sizeof(*(&a[0] + 1)));//16 是对第二行整个一维数组解引用 //计算第二行整个一维数组的大小 printf("%d\n", sizeof(*a));//16 a是二维数组数组名,代表二维数组第一行的地址 //*a就是对第一行解引用,计算第一行整个一维数组的大小 //*a-->*(a+0)-->a[0]-->sizeof(a[0]) printf("%d\n", sizeof(a[3]));//16-->a[3]是一个一维数组,数组类型为int[4] //sizeof只关注()内的数据类型,只关注类型属性 //表达式有两个属性 //1.值属性:即表达式最后的计算结果 //2.类型属性:即表达式计算结果的类型 int a = 7; short s = 4; printf("%d\n", sizeof(s = a + 2));//short 2 printf("%d\n", s);//4 return 0; }