本文主要是介绍每日提问 —— 一维数组和指针的头脑风暴,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
一、分析
二、范例
三、补充
一、分析
说到数组大家都知道是什么,也就是a[MAX],b[MAX],这样的,对了,记得啊,数组的大小在定义的时候一定要确定,或者直接初始化。指针大家应该也是学到了,两者不太简单,结合起来就更有些混乱了。首先先看这个:
int a[] = {1,2,3,4,5};printf(" %x %x %x\n",&a[0] , &a , a);printf(" %x %x %x\n",&a[0]+1 , &a+1 , a+1);
想了解这个问题,首先就要了解第一个printf 中的几个变量是什么意思
&a[0]:数组首元素的地址,走一步一个地址,四个字节
&a:数组的首地址,走一步跨越一个数组
a(退化成了指针):数组首元素的地址,走一步一个地址,四个字节
以下是我自己的一些理解:&a[0] 与 a 都是对数组第一个元素负责,代表的都是首元素的地址,所以当+1 的时候,都是只加上一个元素的地址,从首元素走到了第二个元素的地址,加了四个字节。而 &a 是对整个数组负责,境界拉到了数组层面, +1 的时候就会以数组为单位 +1 ,就会跨越一个数组,也就是20个字节,%x表示以十六进制输出,进一位是十六个字节,所以看上去只加了14,但实际上确实是20个字节。
这个时候就要问了,那 &a[0] 与 a 有什么区别呢?自然是有的,假设一个 &a[x] ,当x = 0 的时候,取到的地址与 a 所指的地址就是一个地方,但是 x 同样可以指向别的地方,在一个数组里,&a[x] 可以指到任何一个内存的地址,这是 a 无法做到的,而 a 专门指向数组首地址,这也是其独特性,我们应该去理解他,在不同的场合下进行自己的判断。
二、范例
int a[4] = {1,2,3,4};int *p1=(int *)(&a+1);int *p2=(int *)((int)a+1);printf("%x,%x",p1[-1],*p2);return 0;
对于这个问题,需要好好想一想
p1:
先进行 &a+1 从数组首地址,跨越一整个数组,指到最后的地址
然后 (int*)(&a+1) 用 int* 强转为整型指针,将这个地址给 p1
最后 p1[-1] 这个 -1 就是往前移动一个整型的地址
p1[-1] 就是这个地方的地址了。
p2: (int *)((int)a+1)
首先数组 a 被弱化为指针 a ,这个里面存放着数组首元素的地址
(int)a 强转为整型变量类型,比如这个地址是0x18330
(int)a+1 +1 就成了0x18331
最后用 (int *) 强转为 int 指针类型,
就是这样啦!
三、补充
如果觉得记得不是很牢固,看看这个:
char arr[] = { 'a','b','c','b' };printf("%d\n", sizeof(arr)); // 4 求 数组所占内存大小printf("%d\n", *(arr+0)); // 97 取a的 ASCII值printf("%d\n", sizeof(*arr)); //1 取首元素值a的内存大小printf("%d\n", sizeof(arr[1])); //1 取b的内存大小printf("%d\n", sizeof(&arr)); //8 取指针内存大小printf("%d\n", sizeof(&arr+1)); //8 跨了一个数组的内存,但是仍然是取指针的内存大小,为8printf("%d\n", sizeof(&arr[0]+1)); //8 取指向arr[1]的指针的内存大小,还是8
看懂这些,理解应该能够更加透彻一些。
以上为个人拙见,如有错误和补充请各位好心同学踊跃提出指正,感激不尽!
这篇关于每日提问 —— 一维数组和指针的头脑风暴的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!