新网创想网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
问题引出:https://freeline.blog.csdn.net/article/details/116484020
成都创新互联是专业的埇桥区网站建设公司,埇桥区接单;提供网站设计、网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行埇桥区网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!#include#includeint main(void)
{
int a[5] = {1,2,3,4,5}; // 000000000065FE00 是十进制的 6684160
// 000000000065FE14 是十进制的 6684180
printf("a = %p\n",a); //a = 000000000065FE00
printf("*a_d = %d\n",*a); // *a_d = 1
printf("*a_p = %p\n",*a); // *a_p = 0000000000000001
printf("&a = %p\n",(&a)); // &a = 000000000065FE00
//
printf("*(&a) = %p\n",*(&a)); // *(&a) = 000000000065FE00
printf("&a+1 = %p\n",(&a+1)); // &a+1 = 000000000065FE14
printf(" *(&a) = %d\n",*(&a)); // *(&a) = 6684160
printf(" **(&a) = %d\n",**(&a)); // **(&a) = 1
printf(" *(&a + 1) = %d\n",*(&a + 1)); // *(&a + 1) = 6684180
printf(" **(&a + 1) = %d\n",**(&a + 1)); // **(&a + 1) = 0
printf("*a = %d\n",(*a)); // *a = 1
printf("*(a + 1) = %d\n",(*(a + 1))); // *(a + 1) = 2
*(&a) = 000000000065FE00, a = 000000000065FE00,
&a[0] =000000000065FE00,以上三个都是指向数组首元素维度的指针
&a = 000000000065FE00,指向整个数组维度的指针
return 0;
}
逐条分析:
(1)a是数组名,a的值是数组第一个元素a[0]的地址,从第一条的结果来看,说明a这个数组的地址(也就是a[0]的地址,是000000000065FE00)。
(2)*a,相当于取a[0]地址上的值,自然将会得到a[0]的值,也就是1。
(3)用%p打印*a,是为了表示%p和%d的区别是只是用十六进制打印还是用十进制打印,其数值是不受影响的。用%x打印地址也是16进制,数值和%p打印出来的一样,只是形式不同:比如打印同一个地址时:%x为65fe00,%p为000000000065FE00。
%号后的字母,表示对同一数值打印方式有区别,但操作对象都是同一个数值。
(4)&a,相当于取数组a的地址,数组的地址就是数组首元素的地址,
所以&a = &a[0] = a,数组名 = 数组首元素的地址 = 数组的地址。
(5)*(&a):错误想法:&a,a = &a[0],相当于&a[0],所以*(&a[0]) = a[0],错!
a表示的是数组的地址,在数值上是a[0]的地址,但是其也是整个数组的地址,对于数组来说,数组的地址也是数组第一个元素的地址,a与&a,这两者在数值上相同,在维度上不同。&a,相当于取整个数组的地址,&a实际上是一个指向整个数组的指针,是int* *类型的。a,相当于指向数组第一个元素的指针,是int*类型的。数值上相同,但意义上未必相同。
所以,*(&a),&a是一个指向数组的指针,对&a进行*操作,将会得到数组a的地址,也就是&a[0]。
(6)&a + 1,&a是以整个数组作为颗粒度的,所以&a + 1,会增加数组a的大小个,所以会在a的值上增加sizeof(int)*sizeof(a)的大小,也就是4 * 5 = 20。
(7)同 (5)
(8)**(&a),相当于取a[0]的值,也就是1。&a是一个指向数组(颗粒度)的指针,*(&a),取数组的地址,相当于一个指向数组首元素的指针;**(&a),相当于得到数组首元素的值。
(9)*(&a + 1),&a + 1,是指向数组维度的,(&a + 1)相当于指向与数组a在内存中邻近数组的指针,*(&a + 1)相当于指向这个邻近数组首元素的指针,也是一个地址,并且这个地址和前面的(6)是相同的数值。
(10)**(&a + 1),得到的值为a的邻近数组的首元素的值,这个和内存有关,可能是随机的值。
(11)*a,a是指向数组首元素的指针,在数值上等于首元素的地址,所以*a = a[0] = 1。
(12)*(a + 1):a是指向数组首元素的指针,是数组元素维度的,所以a + 1指向的是数组的下一个元素,也就是a[1]的地址。
数组名与首元素的关系:数组名是指向首元素的指针,数组名的值是首元素的地址,数组名是以数组元素为颗粒度的指针常量。
注意,a是指向数组元素维度的,指向了数组首元素的地址,&a是指向整个数组维度的,相当于有些二级指针的意思,两者数值相同,含义不同,所以进行相同的操作时,得到的结果也是不同的。
内容补充,建议看看:数组名和数组名取地址& 的区别_wangkeyen的博客-博客_数组名作为类型,作为地址,对数组名取地址的区别
实际上,不用过分纠结于为什么数组名也是等于数组的地址,因为C语言中就是这么规定的,数组名本身的取值,在数值上就是数组的地址,就是数组首元素的地址,数组名是面向数组元素的指针,&a是面向数组的指针,但是两者的维度是不同的,在数值上是相同的。
与数组相同的,函数名也表示函数所在的地址,比如有一个函数int Add(int, int),其中,Add = &Add,这两者在数值上也是相同的,在C语言中,函数名的数值就是函数的地址。
函数指针的相关内容参考:
C语言函数名、&函数名、*函数名_chen_dunyun的博客-博客_函数名
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧