对数组名取地址

int a[5]={1,2,3,4,5};

int b[100];

一个数组名代表的是数组中第一个元素的位置,通过数组名我们可以访问数组,先看下面两个问题

问题一:
看到一篇文章这么写的。。
int array[10];
int (*ptr)[10];
ptr=&array;//这里说明&array是指向数组的指针,但为什么&array是指向数组的指针?
答一:
对数组名取地址在C标准里面是未定义的行为。由于数组名是右值,而&操作符要求操作数具有具体的内存空间,换言之就是一个变量,因此对数组名取地址本来就是非法的,早期的编译器明确规定这是非法的。不过不知道什么原因,现在的编译器多数把&array定义为一个值跟array相同,类型是一个指向数组的地址,注意了,是地址,不是指针。之所以是指向数组的地址,是因为array是一个数组名,它就代表了int array[10]这个数组。而ptr也是定义为一个指向具有10个int数的数组的指针,因此&array能被赋予ptr。
问题二:
对于数组b[],b是数组的地址,但b不算变量,有没有一个地方存放b?而且b是不
是存放的就是自己所在的地址。因为我碰到了如下的问题:
定义一个指针数组
char *a[2];
那么a的值和&a的值是不是应该一样?
答二:
数组名是符号地址常量,在编译时求值并存在编译器的符号表里面,其值就是个内存地址;所以你说的有没有一个地方存放b,可以认为程序没有给其分配空间,数组名只是代表了那个数组空间;与指针不一样,指针指向一块空间,同时指针本身也存储在某个空间;可以认为数组名存在在符号表里,符号表是编译器用的,我们管不到;a和&a值是一样的,本来对常量取地址是非法的,但是标准组织没有定对数组名取地址是非法还是合法,所以因编译器而异,VC是合法的。


然后我们来看一段测试Demo

#include <stdio.h>
int main()
{
int a[5]={1,2,3,4,5};
int b[100];
int *ptr=&a+1;
         printf("%d,%d/n",*(a+1),*(ptr-1));
    printf("sizeof(b)=%d/n",sizeof(b));
    printf("sizeof(&b)=%d/n",sizeof(&b));
}

结果如下

为什么ptr-1的大小是5呢?是否你也像我一样认为是2,1呢?

对指针进行加1操作,得到的是下一个元素的地址,一个类型为T的指针移动,以sizeof(T)为移动单位,

如果ptr=a+1,那么最终输出*(ptr-1)肯定是2,1

但是ptr=&a+1,为什么就是2,5呢?

虽然前面我们讲对数组取地址不合法,但是我们这样做在编译器看来确实获得了数组a的首地址,&a是一个指向 int[5] 的指针。但是这时候ptr相当于int *[5],也就是指向了一个含有五个元素的数组,这也就不难解释为什么第二个打印出来&b的大小也是400了,sizeof(b)打印出来的是b数组的大小。sizeof(&b)同样也是。

为此我们将他们的地址打印出来查看

#include <stdio.h>
int main()
{
int a[5]={1,2,3,4,5};
int b[100];
int *ptr=&a+1;
         printf("%d,%d/n",*(a+1),*(ptr-1));
    printf("sizeof(b)=%d/n",sizeof(b));
    printf("sizeof(&b)=%d/n",sizeof(&b));
    printf("a的地址%d/n",a);
    printf("&a的地址%d/n",&a);
    printf("&a+1的地址%d/n",&a+1);
    printf("ptr-1的地址%d/n",ptr-1);
}

不难看出,&a+1的地址是&a地址再加5*sizeof(int);它的运算单位是int (*)[5]

最后ptr-1,ptr-1的单位是ptr的类型,因此ptr-1的位置刚好是a[4],他在内存中的分布位置是和&a+1相邻的

时间: 2024-12-15 15:14:34

对数组名取地址的相关文章

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语言 对数组名取地址

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

数组名和数组名取地址、指针数组和数组指针的区别

一,首先我们先分析下数组名和数组名取地址的区别. 我们都知道数组名是数组的首地址,然而对数组名取地址又是什么那?看下面一段程序你就会懂的. #include "stdafx.h"     #include<stdio.h>    using namespace std;    void main()    {          int a[5];          printf("%d\n", a);          printf("%d\n

数组名和数组名取地址的区别

数组名和数组名取地址的区别 以下代码会打印出什么样的日志呢? [cpp] view plaincopy #include <stdio.h> int a[2] = {1,2}; int main(){ printf("a = %p\n", a); // I printf("&a = %p\n", &a); // II printf("a + 1 = %p\n", a + 1);// III printf("&

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

http://blog.csdn.net/zdcsky123/article/details/6517811 相信不少的C语言初学者都知道,数组名相当于指针,指向数组的首地址,而函数名相当于函数指针,指向函数的入口地址.现在又这样一个问题,如果对数组名取地址,那得到的会是什么呢?很多人立刻会想到:给指针取地址,就是指针的指针,既二级指针嘛!当然这样的结论是错误的,不然这篇笔记也就没有意义了. 下面我们来逐步分析,下面是一段验证这个问题的代码 Code: #include<stdio.h> in

数组名取地址以及数组名作为sizeof操作符的操作数

数组名取地址十分好玩,在这里记录一下,如果大家有不同见解,欢迎留言探讨: 在大多数情况下,数组名都会默认转换为指向数组的第一个元素的指针.这一点相信大家都知道.比如下边的例子:   int array[3] = {1,2,3};      cout << *array << endl;      cout << array[0] << endl; 上边的两个输出的值是相同的,这个时候array作为数组名默认转换为指向数组的第一个元素的指针.对数组名称进行解引

数组名a、数组名取地址&amp;a、数组首地址&amp;a[0]、数组指针*p

本文链接:https://blog.csdn.net/loongkingwhat/article/details/78910921 数组和指针向来就是傻傻分不清,当他们一起出现的时候就更加懵逼. 1 解析不同变量之间的区别: 数组名a: 数组名可以作为数组第一个元素的指针.我们由数组和指针的关系知道,a代表这个地址数值,它相当于一个指针,指向第一个元素(&a[0]),即指向数组的首地址.数组中的其他元素可以通过a的位移得到,此时的进阶是以数组中单个的元素类型为单位的,即a+i= & a[i

数组名的地址,和数组名取地址的讨论

这个问题的发现是在以下的代码中发现的: #include<stdio.h> int main() {     int arr[2]={1,2};     printf("%p",arr);     printf("%p",&arr);     return 0; } 在运行之后我们发现的数组名本身的地址和数组名内部存储的地址是完全一样的,我们把数组名理解为一个const的指针(数组名只能作为右值,而不是左值),而&arr到底是什么? 我尝