C语言的数组名和对数组名取地址

http://blog.csdn.net/zdcsky123/article/details/6517811

相信不少的C语言初学者都知道,数组名相当于指针,指向数组的首地址,而函数名相当于函数指针,指向函数的入口地址。现在又这样一个问题,如果对数组名取地址,那得到的会是什么呢?很多人立刻会想到:给指针取地址,就是指针的指针,既二级指针嘛!当然这样的结论是错误的,不然这篇笔记也就没有意义了。

下面我们来逐步分析,下面是一段验证这个问题的代码

Code:

  1. #include<stdio.h>
  2. int main()
  3. {
  4. int a[10];
  5. printf("a:/t%p/n", a);
  6. printf("&a:/t%p/n", &a);
  7. printf("a+1:/t%p/n", a+1);
  8. printf("&a+1:/t%p/n", &a+1);
  9. return 0;
  10. }

大家可以编译运行一下,我的输出的结果是:

Code:

  1. /*
  2. a:          0012FF20
  3. &a:         0012FF20
  4. a+1:        0012FF24
  5. &a+1:       0012FF48
  6. */

a和&a指向的是同一块地址,但他们+1后的效果不同,a+1是一个元素的内存大小(增加4),而&a+1增加的是整个数组的内存大小(增加40)。既a和&a的指向和&a[0]是相同的,但性质不同!

读到这里,有很多朋友已经明白其中的机制了,如果还是有些模糊,请继续往下看

Code:

  1. int main()
  2. {
  3. int a[10];
  4. printf("%d/n",sizeof(a));
  5. return 0;
  6. }

这段代码会输出整个数组的内存大小,而不是首元素的大小,由此我们是否联系到,sizeof(a)这里的a和
&a有些相同之处呢?!  是的,没错,&a取都得是整个数组的地址!既数组名取地址等价于对数组取地址。

好了,让我们总结一下,如果你还是不太理解,不用担心,下面的概念很清晰

其实a和 &a结果都是数组的首地址,但他们的类型是不一样。
a表示&a[0],也即对数组首元素取地址,a+1表示首地址+sizeof(元素类型)。
&a虽然值为数组首元素地址,但类型为:类型 (*)[数组元素个数],所以&a+1大小为:首地址+sizeof(a)。

还有这篇文章最初提到的指针的指针的那个错误结论,其实即使不懂上述内容,也应该判断出结论是错误的,大家应该在了解数组名即是数组的首地址的同时,也要知道,数组名仅仅是“相当”于指针,而并非真的是指针,数组名是只是个常量(一个值为数组首元素地址的常量),所以不能进行++或者--运算。而常量更是无法取地址的,而之所以有&a,其实这里的a的意义早已经不是当初那个数组名了,它此时代表了整个数组。

时间: 2024-10-13 16:45:56

C语言的数组名和对数组名取地址的相关文章

C语言 对数组名取地址

作者 : 卿笃军 你有没有想过,对一个一维数组名取地址,然后用这个地址进行加减运算.这会出现什么样的结果呢? 示例: int a[5] = {1,2,3,4,5}; int *p = (int *)(&a+1); printf("%d\n",*(p-1)); 这个输出会是多少呢? 咦?为什么第二行需要强制转化类型呢? 答:a是一个一维数组的名字,&a相当于一个指向一维数组的指针.怎么感觉这么熟悉?指向数组的指针,那不就是行指针吗?int (*p)[]. 行指针+1,就是

C语言中对数组名取地址

在C/C++中,数组名相当于一个指针,指向数组的首地址.这里"相当于"不代表等于,数组名和指针还是有很多区别的,这个在<C陷阱与缺陷>里有详尽的讲述.而这里要说的是对于数组名取地址的这么一个操作. 如果声明有如下数组: int arr[5]; 那么,&arr这个操作得到了什么值呢? 如果简单的认为arr就是一个指向数组首地址的指针的话,那么很自然会想到&arr得到的是一个指向存放arr这个指针的指针,也就是一个二级指针,然而事实却并不是这样. 观察以下代码:

C语言对数组名取地址

你有没有想过,对一个一维数组名取地址,然后用这个地址进行加减运算.这会出现什么样的结果呢? 示例: int a[5] = {1,2,3,4,5}; int *p = (int *)(&a+1); printf("%d\n",*(p-1)); 这个输出会是多少呢? 咦?为什么第二行需要强制转化类型呢? 答:a是一个一维数组的名字,&a相当于一个指向一维数组的指针.怎么感觉这么熟悉?指向数组的指针,那不就是行指针吗?int (*p)[]. 行指针+1,就是对指针进行加减操作

【C语言探索之一】二维数组,二维数组名的意义

1.一维数组 一维数组名,代表两个(1)代表整个数组(虽然谭老爷子的书上说不能,但是只是那个情境下) (2)代表首地址 2.二维数组 想到二维数组在指针方面的理解很是麻烦,所以我自己想了一种理解方式,如下图所示 二维数组名的意义感觉很难受,所以自己来探索下其代表些什么 下面是我的代码和结果 可以看到他们四个的值是一模一样的,但是意义不一样的 1.b数组名,他是指向整个数组的指针, 2.*b是数组第一维的首地址,相当于b[0] 3.&b目的是为了看出数组名的地址,最后结果显而易见,他的地址也是这个

C语言--一维数组和多维数组数组名的含义

一.一维数组 对于一维数组,我们很容易理解数组名和元素地址的关系,即数组名代表数组首地址,亦即第一个元素的地址. 如定义数组int a[9]={1,2,3,4,5,6,7,8,9},则由上面的说明可得 a=&a[0],*a=a[0]: a+1=&a[1],*(a+1)=a[1]: ......... 二.二维数组 对于二维数组,我们一定要记住:它是数组的数组.如定义一个二维数组int b[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},此时我们知道,可以把b看做是一个

C语言中与指针相关问题——论数组名和数组名取地址的关系

这是由一道面试题联想到的一些问题,这里自己给做个小总结! 首先看看这道面试题: #include <stdio.h> int main() { int a[5] = { 1, 2, 3, 4, 5 }; int *pi = &a + 1; printf("%d, %d\n", *(a + 1), *(pi - 1)); return 0; } 答案是2, 5.至于是为什么,我后面说一下我自己的理解. 这里有个要注意的地方,以上代码在CodeBlock中会有个警告,但

读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组

原文链接:C语言结构体里的成员数组和指针 复制如下: 单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接.微博截图如下.我觉得好多人对这段代码的理解还不够深入,所以写下了这篇文章. 为了方便你把代码copy过去编译和调试,我把代码列在下面: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h>

C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 本文由 arthinking 发表于315 天前 ⁄ itzhai.com原创文章 ⁄ C语言 ⁄ 评论数 3 ⁄ 被围观 1,775 views+ 指针数组: 在一个数组中,如果它的元素全部都是指针类

C语言基础学习2:字符数组

在C语言的基本数据类型中没有没有字符串变量,一般以字符数组的形式给出. 1.字符串数组的初始化 char c[] = {'I', ' ', 'a', 'm', 'h', 'a', 'p', 'p', 'y'}; char c[] = "I am happy"; 区别:第一种方式字符串长度为10,内存中占10*sizeof(char)个字节,第二种方式是以字符串形式表示,有一个字符串结束字符'\0',内存中占11*sizeof(char)个字节. 2.字符数组的输入输出 %c,一个一个字