C语言中对数组名取地址
在C/C++中,数组名相当于一个指针,指向数组的首地址。这里“相当于”不代表等于,数组名和指针还是有很多区别的,这个在《C陷阱与缺陷》里有详尽的讲述。而这里要说的是对于数组名取地址的这么一个操作。
如果声明有如下数组:
int arr[5];
那么,&arr这个操作得到了什么值呢?
如果简单的认为arr就是一个指向数组首地址的指针的话,那么很自然会想到&arr得到的是一个指向存放arr这个指针的指针,也就是一个二级指针,然而事实却并不是这样。
观察以下代码:
int arr[5];
printf("%p\n%p\n", arr, &arr); int *pointer = new int[5];
printf("%p\n%p\n", pointer, &pointer);
在我的电脑上运行的结果如下:
0024FC08
0024FC08
0042B158
0024FBFC
我们可以看到,这里pointer这个指针确实如我们所想指向了不同的地址,但是,arr这个数组名的表现却和指针不同,arr和&arr指向的地址是一样的。
这里便体现除了数组名和指针的一个不同之处:对数组名进行&操作,并不是取其地址,而是得到了指向整个数组的指针。也就是说,arr与&arr指向的是同一个地址,但是他们的类型不一样。arr相当于&arr[0],类型是int *,而&arr是指向整个数组的指针,类型是int (*)[5]。
而这样的区别显然也会在对指针或者数组名的加减操作中体现出来,看如下代码:
int arr[5] = { 1, 2, 3, 4, 5 };
printf("%d\n", *arr);
printf("%d\n", *(arr + 1));
printf("%d\n", *((int*)(&arr + 1)));
printf("%d\n", *((int*)(&arr + 1) - 1));
输出为:
1
2
-858993460
5
前两个输出是很好理解的,对指针的加一操作会使指针按照指针的类型移动相应的位置。
第三行输出中,首先得到了指向整个数组的指针,对其进行加一操作,指针就指向了整个数组后面的地址,也就是5后面的地址,那么此时将其转化为int*类型再输出,就得到了该未初始化过的值。
第四行输出中,过程为,指针指向5后面的地址,转为int*类型,此时的减一操作使指针移动一个int类型大小的地址空间,那么便指向了5。
这种特性推广到二维至多维指针的情况下都是类似的。

C语言中对数组名取地址的更多相关文章
- 搬运1:关于对C语言中数组名取地址加减等操作的一点探究
对于数组名取地址强制转换的操作 偶然在晚上学了C语言指针后网页闲逛找题时,被一个数组名取地址搞糊涂了,在自己试验加探索后我稍微悟了一点东西. 代码如下: #include<stdio.h> ...
- C语言的数组名和对数组名取地址
http://blog.csdn.net/zdcsky123/article/details/6517811 相信不少的C语言初学者都知道,数组名相当于指针,指向数组的首地址,而函数名相当于函数指针, ...
- C语言 对数组名取地址
作者 : 卿笃军 你有没有想过,对一个一维数组名取地址,然后用这个地址进行加减运算.这会出现什么样的结果呢? 演示样例: int a[5] = {1,2,3,4,5}; int *p = (int * ...
- 对数组名取地址 a[ ],&a
C语言规定,数组名代表数组的首地址,也就是第0号元素的地址.所以a==&a[0] 但对数组名取地址时却要注意了,在理解“对数组名取地址”这一表达式的含义时一定要记住:数组名是“数组”这种变量的 ...
- 数组名取地址所算数运算应注意的"trap"
数组名取地址所算数运算应注意的"trap" 直接看代码: #include <stdio.h> int main() { int array[5]; printf(&q ...
- 数组名和数组名取地址&
在C中, 在几乎所有使用数组的表达式中,数组名的值是个指针常量,也就是数组第一个元素的地址. 它的类型取决于数组元素的类型: 如果它们是int类型,那么数组名的类型就是“指向int的常量指针“ ...
- C语言指令数组名和数组名取地址
以下C语言指令:int a[5] = {1, 3, 5, 7, 9}; int *p = (int *)(&a + 1); printf("%d, %d", *(a + 1 ...
- C语言数组名取地址。。。
int main(){ int a[5] = { 1, 2, 3, 4, 5 }; printf("%08X ,%08X ,%08X ,%08X", a, &a, a + ...
- 对数组名取地址&a和 数组首地址a
#include <iostream> using namespace std; ] = {,,,,}; int main() { cout<<a<<" ...
随机推荐
- oracle执行update语句时卡住问题分析及解决办法
转载:http://www.jb51.net/article/125754.htm 这篇文章主要介绍了oracle执行update语句时卡住问题分析及解决办法,涉及记录锁等相关知识,具有一定参考价值, ...
- ASP.NET MVC验证框架中关于属性标记的通用扩展方法
http://www.cnblogs.com/wlb/archive/2009/12/01/1614209.html 之前写过一篇文章<ASP.NET MVC中的验证>,唯一的遗憾就是在使 ...
- 【leetcode】Path Sum2
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...
- hdu 4857 Little Devil I
http://acm.hdu.edu.cn/showproblem.php?pid=4897 题意:给你一棵树,边的颜色要么为白色,要么为黑色,初始每条边为白色,有三种操作 1.将u-v链上面的所有边 ...
- bzoj千题计划187:bzoj1770: [Usaco2009 Nov]lights 燈 (高斯消元解异或方程组+枚举自由元)
http://www.lydsy.com/JudgeOnline/problem.php?id=1770 a[i][j] 表示i对j有影响 高斯消元解异或方程组 然后dfs枚举自由元确定最优解 #in ...
- 官方资料&一些好的博客与技术点
https://technet.microsoft.com/zh-cn/library/hh848794.aspxzh https://msdn.microsoft.com/en-us/power ...
- Java SpringMVC框架学习(三)springMVC的执行流程
具体执行逻辑如下: 浏览器提交请求到中央调度器. 中央调度器将请求转给处理器映射器. 处理器映射器根据请求, 找到请求对应的处理器, 并将其封装为处理器执行链返回给中央调度器. 中央调度器根据处理器执 ...
- html5 canvas显示文字(写上5个字,纪念我那刚刚逝去的爱情)
<script type="text/javascript"> window.addEventListener('load',eventWindowLoaded,fal ...
- html5 canvas 奇怪的形状垂直渐变
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 使用data:uri上传图片
上传图片的方式有两种,一种是使用传统的html控件的方式,设置form属性为multipart/form-data.这种方式兼容ie6,ie7.另一种方式是使用data:uri,将base64编码从浏 ...