数组名和指针的区别和联系、数组名取地址a
前言
- 在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向该数组首元素的指针。
- 所以,在大多数表达式中,使用数组名其实是在使用一个指向该数组首元素的指针。
数组名其实是种特殊的指针
int main()
{int a[] = { 0,1,2,3,4 };printf("a is %x\n", a);printf("&a is %x\n", &a);printf("&a[0] is %x\n", &a[0]);int *p = &a[0];//int * p1 = &a;//上句报错信息:&a的类型为int(*)[5],不能用来初始化int *decltype(a) t;decltype(&a) tt;cout << "p is "<<p << endl;printf("a + 1,p + 1 are %x,%x\n", a + 1,p + 1);printf("&a + 1 is %x\n", &a +1);cout << sizeof(a) << " " << sizeof(&a) << endl;
}
- 从局部变量表可以看出,数组a和指针p的构成是很相似的。它们实际存的都是一个地址,都会指向一个对象(或多个对象的第一个对象)。所以说数组名其实是种特殊的指针。
- 但它俩自身又有不同,指针本身是一个对象,在内存中是为其分配了空间的;但数组名在内存空间中没有分配到空间(这将导致
&a
操作的效果可能和预想的不大一样)。
数组名a、数组名取地址&a、数组首元素地址&a[0]、指向数组首元素的指针*p
a
既然是种特殊的指针,那么其打印时就会是存的地址。&a
的类型是int(*)[5]
(读法从小括号里往外,首先是指针,然后是大小为5的数组,然后数组元素类型是int),从局部变量中看到其类型也可写成int[5] *
:即指向大小为5的int数组的指针。由于数组名没有内存分配空间,所以&a
取地址还是取到的是数组首元素的地址。&a[0]
就是取一个int对象的地址,这个int对象是数组首元素。综上所述,就造成了a &a &a[0]
三者打印出来的地址是一样的。p
,指向数组首元素的指针。a + 1,p + 1
都是按照元素大小的字节数(4字节),增加4。&a + 1
,前面说了&a
的类型是指向大小为5的int数组的指针,大小为5的int数组所占字节数为20,所以&a + 1
就应该增加20。sizeof(a)
为20,因为数组总的字节大小为20。sizeof(&a)
为4,因为&a
是一种指针,指针在32位系统中占4字节。
指向数组首元素的指针可使用操作符[]
a[1], p[1]
都能取出数组的1索引元素。
上面这句的效果和原理和这句*(a + 1),*(p + 1)
一样。
对了,你也可以int *p = a
,也是指向数组首元素的指针。
指向非首元素的指针使用操作符[]
int *p = &a[2]
指向了2索引的元素。
int j = p[1]
,3索引的元素。相当于*(p + 1)
。
int k = p[-2]
,0索引的元素。这里是内置的取下标操作,所以可以用有符号数。(标准库类型取下标的话,则必须使用无符号数)
但一定注意这里的p都必须指向数组中的元素。
数组名和指针的区别和联系、数组名取地址a相关推荐
- char[]数组与char *指针的区别
char[]数组与char *指针的区别 问题描述 虽然很久之前有看过关于char指针和char数组的区别,但是当时没有系统的整理,到现在频繁遇到,在string,char[], char *中迷失了 ...
- 神奇的判断数组名和指针的区别
神奇的判断数组名和指针的区别 代码 代码 傻傻的区分不清楚数组名和指针的区别,下面的代码可以证明指针和数组名其实不是一个东西: // An highlighted block #include< ...
- 从编译器角度分析C语言中数组名和指针的区别
从编译器角度分析C语言中数组名和指针的区别 数组名和指针是两个往往很容易让人们混淆的概念,很多人以为数组名就是一个指针,也有很多人知道数组名不同于指针但是仅知道数组名的值不能像指针一样改变. 例如你可 ...
- 类中数组成员变量怎么初始化,数组名与指针的区别
使用STL标准模板库之后,编程时已经很少使用数组和指针,相反,多使用序列容器vector代替之. (std::vector<int>,构造函数接受const std::vector< ...
- C语言中数组名和指针的区别
1: 指针是一个变量,而数组名不是.数组名是数组的首地址,即它本身就是一个地址. 2:假设a是一个数组名,而p是一个指针,当你使用 a 和 &a 时,得到值是一样的,都是数组的起始地址.而使用 ...
- 字符串数组和字符串指针的区别
基本知识:数组要么在静态存储区被创建(如全局数组),要么在栈上被创建.数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变.而指针是动态变换的,它指向的指针可以随 ...
- 字符数组与字符指针的区别
1.字符指针可以指向一个字符串. 我们可以用字符串常量对字符指针进行初始化.例如,有说明语句: char *str = "This is a string."; 是对字符指针进行初 ...
- C语言—字符串与字符数组,字符串数组与字符串指针的区别
字符串与字符数组 字符串一定是一个char的数组,但char的数组未必是字符串.--以字符'\0'结尾的char数组就是一个字符串,但如果char数组没有以'\0'结尾,那么就不是一个字符串,只是普通 ...
- c++ 二维数组_C|数形结合理解数组指针、指针数组、一级指针来遍历二维数组
二维数组本质是也是线性存储的一维数组,各元素都是相对于基地址(首地址)的偏移,只是逻辑上的维度区分而已.或者可以理解为数组的数组,也就是说,n维数组的元素是一个n-1维数组. 需要注意的是,多维数组名 ...
最新文章
- 豆瓣评分 9.3,史上最好的 C 语言著作,竟然翻车了......
- python游戏服务器框架_Scut游戏服务器免费开源框架--快速开发(2)
- vim常用命令使用总结
- h5的语义化部分_H5 部分新语义化标签
- STM32F103_USART_GPIO配置及相应的IO口设置
- kafka(一)-为什么使用kafka
- python基础(part8)--容器类型之元组和字典
- 使用Java Stream API将List按自定义分组规则转换成Map的一个例子
- eyoucms内容添加发布
- python产生随机数_python技能:random库的使用
- 国内达梦数据库相关函数-时间日期
- 手把手教你开发-滚动效果号码抽奖(QT)
- 在虚拟机中安装Windows XP
- OpenGL with QtWidgets:屏幕坐标转世界坐标
- 微信小程序转码机器人
- larvel html转pdf文件,如何在Laravel中使用TCPDF从HTML生成PDF
- 一个关于意念(脑电波)的想法
- 搭建网站的主要目的、基本步骤和技巧
- 超详细的gnuplot使用教程【2】
- 数学建模之规划1——线性规划