✨✨✨学习的道路很枯燥,希望我们能并肩走下来!
编程真是一件很奇妙的东西。你只是浅尝辄止,那么只会觉得枯燥乏味,像对待任务似的应付它。但你如果深入探索,就会发现其中的奇妙,了解许多所不知道的原理。知识的力量让你沉醉,甘愿深陷其中并发现宝藏。
本篇对于进一步了解指针和数组有更多的帮助,对指针,数组的练习进行总结,如有错误,请在评论区指正,让我们一起交流,共同进步!
本文开始
知识了解:数组名的意义
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. & 数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。
题目:
int a[] = {1,2,3,4};
printf(“%d\n”,sizeof(a));
printf(“%d\n”,sizeof(a+0));
printf(“%d\n”,sizeof(a));
printf(“%d\n”,sizeof(a+1));
printf(“%d\n”,sizeof(a[1]));
printf(“%d\n”,sizeof(&a));
printf(“%d\n”,sizeof(&a));
printf(“%d\n”,sizeof(&a+1));
printf(“%d\n”,sizeof(&a[0]));
printf(“%d\n”,sizeof(&a[0]+1));
代码详解:
int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//16
//a是数组名 单独 放在sizeof()中代表整个数组,是一种特殊情况
printf("%d\n", sizeof(a + 0));//4/8
//是地址,首元素地址,数组名a 不是单独放在sizeof内部,也没有&
//地址大小取决于平台,32位平台4个自己,64位平台8个字节(是地址大小就是4或8个字节)
printf("%d\n", sizeof(*a));//4
//a是首元素地址,*a是首元素大小
printf("%d\n", sizeof(a + 1));//4/8
//a非单独放置,a是首元素地址,a+1(跳过一个int)是第二个元素的地址
printf("%d\n", sizeof(a[1]));//4/8
//a[1]是数组的第二个元素
printf("%d\n", sizeof(&a));//4/8
//&a取出的数组的地址,数组的地址一样是地址,地址就是4/8个字节
//a - int* - 整形指针
//&a - int(*)[4] - 数组指针
//两者地址值一样,但意义不同,+1走的不同
printf("%d\n", sizeof(*&a));//16
//&a是数组的地址,是数组指针类型,*&a是数组指针的解引用,访问一个数组的大小
//sizeof(*&a) <==> sizeof(a)
printf("%d\n", sizeof(&a + 1));//4/8
//&a数组的地址,&a+1跳过整个数组,&a+1还是地址
printf("%d\n", sizeof(&a[0]));//4/8
//a[0]是数组的第一个元素,&a[0]是第一个元素的地址
printf("%d\n", sizeof(&a[0] + 1));//4/8
//&a[0]是第一个元素的地址,&a[0]+1就是第二个元素的地址
return 0;
}
sizeof 是计算对象或者类型创建的对象所占空间的大小
sizeof- 是操作符,不是函数
char arr[] = {‘a’,‘b’,‘c’,‘d’,‘e’,‘f’};
printf(“%d\n”, sizeof(arr));
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));
①字符数组 (数组元素为单字符 ‘x’)sizeof 求字节数
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//6
//arr是数组名,并且是单独放在sizeof内部,计算的是数组总大小 - 6
printf("%d\n", sizeof(arr + 0));//4/8
//arr非单独放在sizeof内部,arr是首元素的地址 - 4/8
printf("%d\n", sizeof(*arr));//1
//arr非单独放在sizeof内部,arr是首元素地址,*arr是首元素,计算的是首元素大小 - 1
printf("%d\n", sizeof(arr[1]));//1
//arr[1]是数组的第二个元素,计算的是第二个元素的大小 - 1
printf("%d\n", sizeof(&arr));//4/8
//&arr 取出的是数组的地址,计算的是数组的地址 - 4/8
printf("%d\n", sizeof(&arr + 1));//4/8
//&arr数组地址,&arr + 1 跳过整个数组,指向'f'的后面,但是本质是地址
//没有越界,只是找到地址,但没有取值
printf("%d\n", sizeof(&arr[0] + 1));//4/8
//&arr[0]是'a'的地址,&arr[0]+1是'b'的地址,地址=》4/8
return 0;
}
②字符数组 (数组元素为单字符 ‘x’) strlen 求字符串长度
char arr[] = { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’ };
printf(“%d\n”, strlen(arr));
printf(“%d\n”, strlen(arr+0));
printf(“%d\n”, strlen(*arr));
printf(“%d\n”, strlen(arr[1]));
printf(“%d\n”, strlen(&arr));
printf(“%d\n”, strlen(&arr+1));
printf(“%d\n”, strlen(&arr[0]+1));
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));//随机值
//arr是数组名,非sizeof内部,没有&,arr为首元素地址
//strlen得到arr,从arr数组首元素的地方开始计算字符串的长度,
//直到找到\0,但是数组中没有\0,arr内存的后面是否有\0,出现的位置是随机的(我们不能确定)
printf("%d\n", strlen(arr + 0));//随机值
//arr是数组首元素的地址,arr+0还是首元素地址,原因同上一样产生随机值
printf("%d\n", strlen(*arr));//err
//*arr取的是首元素 'a'
//'a'ASCII码值是 97 ,把97当成地址,我们不知道97地址中存放的是什么会非法访问地址产生错误
printf("%d\n", strlen(arr[1]));//err
//arr[1]是第二个元素'b' - 98 - 原因同上一个非法访问地址产生错误
printf("%d\n", strlen(&arr));//随机值
//&arr是数组地址,也指向数组起始位置
printf("%d\n", strlen(&arr + 1));//随机值,从'f'+ 1地址开始查找
printf("%d\n", strlen(&arr[0] + 1));//随机值,从'b'地址开始查找
return 0;
}
字符数组 (数组元素为字符串"xxx") sizeof 求字节长度
char arr[] = “abcdef”;
printf(“%d\n”, sizeof(arr));
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));
int main()
{
char arr[] = "abcdef";
//字符串中含有\0,注意:\0也属于字符
printf("%d\n", sizeof(arr));//7(计算6是忘记\0字符了,一定要注意)
//arr是数组名,单独放在sizeof中,求的是数组的总字节数
printf("%d\n", sizeof(arr + 0));// 4/8
//arr+0代表数组首元素地址
printf("%d\n", sizeof(*arr));//1
//取的是数组首元素'a',一个字符是1个字节
printf("%d\n", sizeof(arr[1]));//1
//arr[1]是数组第二个元素'b'
printf("%d\n", sizeof(&arr));// 4/8
//&arr是整个数组的地址
printf("%d\n", sizeof(&arr + 1));// 4/8
//&arr+1是跳过整个数组,也是地址
printf("%d\n", sizeof(&arr[0] + 1));// 4/8
//&arr[0]是数组首元素地址,&arr[0]+1是第二个元素的地址
return 0;
}
字符数组 (数组元素为字符串"xxx") strlen求字符串长度
char arr[] = “abcdef”;
printf(“%d\n”, strlen(arr));
printf(“%d\n”, strlen(arr+0));
printf(“%d\n”, strlen(*arr));
printf(“%d\n”, strlen(arr[1]));
printf(“%d\n”, strlen(&arr));
printf(“%d\n”, strlen(&arr+1));
printf(“%d\n”, strlen(&arr[0]+1));
int main()
{
char arr[] = "abcdefg";
printf("%d\n", strlen(arr));//7
//arr数组地址,一样指向数组首元素地址,从首元素地址开始
printf("%d\n", strlen(arr + 0));//7
//arr+0也是数组首元素地址
printf("%d\n", strlen(*arr));//err
//*arr取得是数组首元素'a'
printf("%d\n", strlen(arr[1]));//err
//arr[1]取得是数组元素'b'
printf("%d\n", strlen(&arr));//7
//&arr是数组地址,一样指向数组首元素地址,从首元素地址开始
printf("%d\n", strlen(&arr + 1));//随机值
printf("%d\n", strlen(&arr[0] + 1));//6
return 0;
}
注意:
①p是指针变量,存放的是字符串的地址(a的地址)
②从&p往后数是未知的,结果是随机值
③字符串开辟一块空间存值,指针变量p开辟一块空间存字符串地址
字符指针指向的字符串可能不好理解,可以与下面图结合,容易理解(例如:&p,&p+1的理解)
char *p = “abcdef”;
printf(“%d\n”, sizeof§);
printf(“%d\n”, sizeof(p+1));
printf(“%d\n”, sizeof(*p));
printf(“%d\n”, sizeof(p[0]));
printf(“%d\n”, sizeof(&p));
printf(“%d\n”, sizeof(&p+1));
printf(“%d\n”, sizeof(&p[0]+1));
printf(“%d\n”, strlen§);
printf(“%d\n”, strlen(p+1));
printf(“%d\n”, strlen(*p));
printf(“%d\n”, strlen(p[0]));
printf(“%d\n”, strlen(&p));
printf(“%d\n”, strlen(&p+1));
printf(“%d\n”, strlen(&p[0]+1));
int main()
{
const char* p = "abcdef";
printf("%d\n", sizeof(p));// 4/8
//p是指针存放a的地址
printf("%d\n", sizeof(p + 1));// 4/8
//p+1是指向'b'的指针(地址)
printf("%d\n", sizeof(*p));// 1
//*p是首元素'a'
printf("%d\n", sizeof(p[0]));// 1
//p[0] => *(p+0)是首元素'a'
printf("%d\n", sizeof(&p));// 4/8
//&p是字符串的地址
printf("%d\n", sizeof(&p + 1));// 4/8
//&p+1跳过一个p,4个字节(x86环境下)
printf("%d\n", sizeof(&p[0] + 1));// 4/8
//&p[0]+1是'b'的地址
//a b c d e f \0
printf("%d\n", strlen(p));//6
//p指向'a'的地址
printf("%d\n", strlen(p + 1));//5
//p+1指向'b'的地址
printf("%d\n", strlen(*p));//err
//*p是'a'的值
printf("%d\n", strlen(p[0]));//err
//p[0]是'a'的值
printf("%d\n", strlen(&p));//随机值
//指针p存放的是字符串地址,从&p开始向后找不知道会有什么值,未知
printf("%d\n", strlen(&p + 1));//随机值
//&p+1跳过一个p的地址,p的地址后面是什么也未知
//p中的4个字节所存放的值,也不能保证没有\0
printf("%d\n", strlen(&p[0] + 1));// 5
return 0;
}
二维数组名
sizeof:内部不进行运算
结果最终是(num)short类型=》2
int main()
{
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//48
//a是二维数组的数组名,数组名单独放到sizeof中,计算的数组的总大小,单位字节
printf("%d\n", sizeof(a[0][0]));//4
//a[0][0]是首元素- 一个整形
printf("%d\n", sizeof(a[0]));//16
//把二维数组的每一行看作一维数组的时候,a[0]是第一行的数组名,
//第一行的数组名单独放的sizeof中,计算的是第一行的总大小
printf("%d\n", sizeof(a[0] + 1));// 4/8
//a[0]虽是第一行数组名,但没有单独放到sizeof中
//a[0]作为第一行的数组名并非表示第一行这个数组,a[0]就是第一行首元素地址,a[0] =>&a[0][0]-int*
//a[0]+1,跳过一个int,是a[0][1]的地址
printf("%d\n", sizeof(*(a[0] + 1)));// 4
//a[0]+1是第二个元素的地址,*(a[0]+1)是第二个元素 int
printf("%d\n", sizeof(a + 1)); // 4/8
//a没有单独放到sizeof中,没有&,所有a是首元素的地址
// 可以将二维数组看作一个一维数组,二维数组第一个元素就是二维数组的第一行
//二维数组中 数组名 代表第一行的地址
//a+1就是第二行的地址
printf("%d\n", sizeof(*(a + 1)));// 16
//a+1是第二行的地址,对数组指针解引用,表示第二行的大小
//*(a+1) => a[1]
printf("%d\n", sizeof(&a[0] + 1));// 4/8
//&a[0]是第一行的地址,&a[0]+1是地二行的地址
printf("%d\n", sizeof(*(&a[0] + 1)));// 16
//对第二行解引用就拿到第二行
//*(&a[0]+1) => a[1]
printf("%d\n", sizeof(*a));// 16
//a是首元素的地址,就是第一行的地址 -&a[0]
//*a - 拿到的就是第一行
//*(a+0) ->a[0]
printf("%d\n", sizeof(a[3]));// 16
//能够分析处a[3]的类型是:int [4]
//a[3]是二维数组的第4行,虽然没有第四行,但是类型能够确定,大小就是确定的
//大小就是一行的大小
//任何一个表达式都有2个属性
//3+5 ,1个值属性:8 ,1个类型属性:int
return 0;
}
小结:
✨✨✨各位读友,本篇分享到内容是否更好的让你理解了指针,数组,如果对你有帮助给个赞鼓励一下吧!!
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!