通俗理解:内存就是公寓房间,指针就是房间的门牌号,数组就是连续的公寓房间,数组名就是这组连续房间的起始地址,也就是第一个房间的地址。

例如int a[5]   a是数组名,也就是第一个房间号

&a就是整个数组的门牌号,值和第一个门牌号相等,但是物理意义不一样。

下面是转载自别处

#include<stdio.h>

int main()

{

int a[5];

printf("%d\n",a);   //指向第一个数组元素的首地址            1245036

printf("%d\n",&a);        //指向整个数组的地址                 1245036

printf("%d\n",a + 1);            //a[1]元素的地址                               1245040

printf("%d\n",&a + 1);         //整个数组的字节长度4*5=20           1245056

printf("%d\n",&a[0] + 1);  //下一个元素的地址,下一个门牌号  1245040

printf("%d\n",sizeof(a));

printf("%d\n",sizeof(&a));

return 0;

}

运行结果:

分析:

由运行结果可知,数组名a和&a得内存地址相同。我们由数组和指针的关系知道,a代表这个数字,它相当于一个指针,指向第一个元素(&a[0]),即指向数组的首地址。数组中的其他元素可以通过a的位移得到,此时的进阶是以数组中单个的元素类型为单位的。所以有a+1为1245040,即数组中a[1]的地址是1245040(在首地址1245036基础上加int的字节数4得到的)。

然而,&a代表的不是取a这个变量的地址,而是取数组元素的地址。虽然&a和a得内存地址相同,但它们的意义不相同,它是代表整个数组的,它的进阶单位是整个数组的字节长度(这里是4*5=20),所以&a+1得内存地址为1245056。

其实,a的类型是int[5]   数组

&a的类型是int(*)[5]  指针——指向int[5]数组的指针

&a[0]的类型是int*    指针——指向int类型的指针

另外,当用sizeof时,由于它是个关键词,而不是个函数,所以数组不自动转换为指针,得到的结果是数组的长度*数组中元素类型所占的字节数,本例中sizeof(a)和sizeof(&a)都是20.

ps:如果是(int)a +1,则结果是1245037(即1245036+1)

另一篇博客:

C语言规定,数组名代表数组的首地址,也就是第0号元素的地址。所以a==&a[0]

但对数组名取地址时却要注意了,在理解“对数组名取地址”这一表达式的含义时一定要记住:数组名是“数组”这种变量的变量名

这样,&a就好理解了,它取的是“数组”这种变量的地址

&a+1自然也就要跨过整个数组,所有元素长度总和,这么长的一个长度。例如:inta[10],那么&a+1就要跨过10个int的长度

详细分析——

1 int array[100];

2

3 memset(array,  0, sizeof(array));

4 memset(&array, 0, sizeof(array));

第3行和第4行有什么不同吗?其实从效果上来说是一样的,但是这里要注意 array 和 &array 的类型是不同的。

array 相当于 &array[0],它们都是整型指针。而 &array 是一个指向 int[100] 的指针,这是一个数组指针,类型是 int(*)[100],当用数组指针变量来接收它的值时,你会发现它与整型指针array、&array[0]的巨大不同。

以下代码可以看出这个不同:

#include <stdio.h>

int main()

{

int array[100] = {0, 1, 2};

typedef int (*ARRAY)[100];

int*p1 = array;//数组名代表第0号元素的地址(准确的说应该是代表第0号元素的指针):&array[0],第0号元素是一个整型变量

ARRAYp2 = &array;

int*p3 = &array;//实际上赋值符自动向下兼容,将&array转换为了一个整型变量指针:&array[0]

//或者可能是像空指针可以接收所有类型的指针值一样,各类型的指针都可以接收自己类型的数组指针,并完成兼容性转换,例如int型指针可以接收int数组的数组指针,并转换为int型指针;char型指针可以接收char数组的数组指针,并转换为char型指针。

printf("p1 = 0x%08d\n",  p1);

printf("p2 = 0x%08d\n",  p2);

printf("p3 = 0x%08d\n",  p3);

printf("int=%dbyte\n",sizeof(int));

printf("p1+1=0x%08d\n",p1+1);

printf("p2+1=0x%08d\n",p2+1);

printf("p3+1=0x%08d\n",p3+1);

printf("p1[2] = %d\n", p1[2]);

printf("p2[2] = %d\n", p2[2]);

printf("p3[2] = %d\n", p3[2]);

printf("(*p2)[2] = %d\n", (*p2)[2]);

//printf("(*p1)[2] = %d\n", (*p1)[2]);//这样编译错误

//printf("(*p3)[2] = %d\n", (*p3)[2]);//这样编译错误

getchar();

return 0;

}

运行结果可能是:

从上面的分析以及程序可以发现:

指针与地址其实还是有差异的,指针的属性中包含有地址这个概念,而且对于不同的指针,其地址概念却都是相同的,都是用一个数表示内存条上的某个位置。

但指针的属性中还有大小、距离的概念:

大小——不同类型的指针,其指向的变量所占据的内存大小不同,即从内存条上的起始位置(即地址)开始,所占据的字节数不同。例如int占4个byte,char占1个byte

距离——不同类型的指针移动一个单位,其在内存条上移动的字节数不同。例如int型指针+1则移动4个byte,char型指针+1则移动1个byte,数组型指针+1则移动许多许多个byte

转载 转载 转载 数组a[],a,&a之间的区别的更多相关文章

  1. 【转载】python3.0与2.x之间的区别

    python3.0与2.x之间的区别: 1.性能 Py3.0运行pystone benchmark的速度比Py2.5慢30%.Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可以取得很好 ...

  2. 【转载】CString、BSTR和LPCTSTR之间的区别

    原文:http://www.cnblogs.com/GT_Andy/archive/2011/01/18/1938605.html 一.定义 1.CString:动态的TCHAR数组.它是一个完全独立 ...

  3. (研) int(*p)[10]; int *p[10]; int(*)[10]; 之间的区别

    int *p[10]; 从这个最简单的说起 p先与后面的[4]结合,说明他本质是一个数组 ,“[]”的优先级比“*”要高.p先与“[]”结合,构成一个数组的定义,数组名为p,int *修饰的是数组的内 ...

  4. Ubuntu桌面版本和服务器版本之间的区别(转载)

    转载自:http://blog.csdn.net/fangaoxin/article/details/6335992 http://www.linuxidc.com/Linux/2010-11/297 ...

  5. TCP/IP和UDP之间的区别(转载)

    在分析两者之间的区别之前,我们先搞清楚这两者的关系, TCP/IP协议簇  是一种网络控制协议,简单点说就是一种网络协议,我们网络中的计算机就是通过这套协议簇来进行数据通信的.这套协议簇里面包含了很多 ...

  6. 【转载】String、StringBuffer与StringBuilder之间区别

    文章来源:http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 这两天在看Java编程的书,看到String的时候将之前没有弄懂的 ...

  7. git fetch和git pull之间的区别--转载

    原文地址:http://blog.csdn.net/a19881029/article/details/42245955 git fetch和git pull都可以用来更新本地库,它们之间有什么区别呢 ...

  8. http、TCP/IP协议与socket之间的区别(转载)

    http.TCP/IP协议与socket之间的区别  https://www.cnblogs.com/iOS-mt/p/4264675.html http.TCP/IP协议与socket之间的区别   ...

  9. socket编程中write、read和send、recv之间的区别~转载

    socket编程中write.read和send.recv之间的区别   http://blog.csdn.net/petershina/article/details/7946615 一旦,我们建立 ...

  10. 【转载】 LSTM构建步骤以及static_rnn与dynamic_rnn之间的区别

    原文地址: https://blog.csdn.net/qq_23981335/article/details/89097757 --------------------- 作者:周卫林 来源:CSD ...

随机推荐

  1. 微信小程序 Video默认横屏

    wxml文件 <video id='myvideo' src='你的视频文件路径'> </video> js文件 onLoad: function (options) { va ...

  2. 调整Windows操作系统下时间同步的频率

    今天发现时间不对,同步时间后看到Windows系统默认是一周才同步一次时间,频率太低了.查找了一下资料,找到了两种调整Win7时间同步频率的方法. 方法一:注册表法 这种方法是通过修改注册表中的键值来 ...

  3. .NetCore 下开发独立的(RPL)含有界面的组件包 (六)实现业务功能

    .NetCore 下开发独立的(RPL)含有界面的组件包 (一)准备工作 .NetCore 下开发独立的(RPL)含有界面的组件包 (二)扩展中间件及服 务 .NetCore 下开发独立的(RPL)含 ...

  4. jquery实时监听输入框值变化

    在做web开发时候很多时候都需要即时监听输入框值的变化,以便作出即时动作去引导浏览者增强网站的用户体验感.而采用onchange时间又往往是在输入框失去焦点(onblur)时候触发,有时候并不能满足条 ...

  5. Atcoder ARC101 Ribbons on Tree

    题解: 前面牛客网的那个比赛也有一道容斥+dp 两道感觉都挺不错的 比较容易想到的是 f[i][j]表示枚举到了i点,子树中有j个未匹配 这样的话我们需要枚举儿子中匹配状态 这样是n^2的(这是个经典 ...

  6. 基于jquery的页面分屏切换模板

    闲来无事,搞了个页面的分屏效果,先来看下效果: 出于可自定义宽高的目的,屏幕分块由CSS控制,由js控制估计等分模块效果一般. 程序相关说明: HTML结构: <div class=" ...

  7. 【AtCoder】AGC016

    A - Shrinking 用每个字母模拟一下就行 #include <bits/stdc++.h> #define fi first #define se second #define ...

  8. 使用spark操作kudu

    Spark与KUDU集成支持: DDL操作(创建/删除) 本地Kudu RDD Native Kudu数据源,用于DataFrame集成 从kudu读取数据 从Kudu执行插入/更新/ upsert ...

  9. Python学习(二十五)—— Python连接MySql数据库

    转载自http://www.cnblogs.com/liwenzhou/p/8032238.html 一.Python3连接MySQL PyMySQL 是在 Python3.x 版本中用于连接 MyS ...

  10. python--return小练习

    #返回单个值,return a:#一个return后的语句不再执行,def calc_sum(*args): ax = 0 for n in args: ax = ax + nprint(ax); r ...