数组名不能做自增或自减

http://blog.csdn.net/firefly_2002/article/details/8108468

如下, k 是变量, 它存得是地址, 变量可以作为左值,可以自增。

              b是数组名,  数组名是地址, 但此时是作为常量,不可作为左值,不可以自增; 数组名是地址 它不是变量 数组才是变量

int b[]={10,20,30,40,50};
int i, *k;
k=&b[4]-4;
for (i=0; i<=4; i++)
{
  cout << *k << " "; //依次输出每一个数组元素
  k++; //k 是变量, 它存得是地址, 变量可以作为左值,可以自增。
}
cout<<endl;

cout<<"b = "<<b+1<<endl; //输出的是第一个元素地址
cout<<"&b[0] = "<<&b[0] + 1<<endl;
cout<<"b = "<<b++<<endl; //数组名表示得是地址 不能做为左值 , b++ 表示的是b=b+1
cout<<"&b[0] = "<<&b[0]++<<endl; // &优先级高于++, 同(&b[0])++, 也是地址自增,但此时地址是常量,而不是变量,同上,编译出错

比如说 int a[5],b[3]={1,2}; 你只会 a[1]=b[1]; 这样 。 应该不会a=b把。

数组名不是变量 不能做左值

指针你可以把它看做一个整型(但不是)数据类型 它是一个变量 存储得是一个地址 比如你可以把一个地址赋值给它,这时指针变量就存储这个地址,再把另一个地址赋值给它, 这时指针变量就存另一个地址,它是可以变的,所以可以作为左值。

数组,你声明一个数组,系统就分配了一个内存单元 这时数组名表示得是这个数组首元素得地址,这个地址是不能变得,可以把它看做(但不是)常量,所以不能作为左值 。

从编译器角度分析C语言中数组名和指针的区别       

        分类:            C语言学习 181人阅读 评论(1) 收藏 举报

数组名和指针是两个往往很容易让人们混淆的概念,很多人以为数组名就是一个指针,也有很多人知道数组名不同于指针但是仅知道数组名的值不能像指针一样改变,例如你可以写出下面这样的代码:


  1. int *p;
  2. p++;

却不能写这样的代码:


  1. int a[];
  2. a++;

那么数组名跟指针之间到底有什么区别呢?

第一,在声明上,除了作为函数参数的数组名总是编译器转化成指针其他情况下,数组名就是数组名,指针就是指针,二者不能混淆你不能在一个文件中定义一个数组,而在另一个文件中把它声明成一个指针


  1. char a[]; //定义一个数组a

  2. extern char *a; //在另一个文件中将a声明成一个指针

在编译器中,符号表用来存放C语言中有关标识符的属性信息,这些信息集中反应了标识符的特征属性。等到词法分析到代码声称的各个阶段的时候,编译器需要根据源代码提出的要求,从表中获取不同标识符的不同属性。值得注意的是,数组标识符的属性和指针是完全不同的。因此,在一个文件中定义一个数组的时候,编译器会把它记录在符号表中,而在编译器分析另一个文件中的声明时,通过符号的语义检查发现不一致。也许这样的声明可以编译通过(在gcc下通过了),但是把一个数组名当成一个指针来使用,别指望它能运行起来。

第二指针是一个变量,而数组名不是。数组名是数组的首地址,即它本身就是一个地址,对应到汇编语言级别就是一个常量,一个固定的数(地址)。因此数组名不能进行++,–等运算。

在大多数编译器中,对数组的引用a[i]总是被编译器改写成*(a+i)的格式。也就是说,编译器每遇到a[i],都会把它当作*(a+i)来处理。我们都知道,*addr表示内存中(addr)的位置存储的值,比如*0×8048000就表示地址为0×8048000的内存中所存储的值。所以a[i]就表示a的值加上i所得到的数作为一个内存地址里面所存储的值。

那么a的值是什么呢?编译器在做词法分析和语法分析的时候,遇到一个数组的定义,就会把数组的有关信息汇集在一个叫做“内情向量”或“信息向量”的表各种,其中的信息包括数组的类型,维数,各维的上、下边界,以及数组的首地址,然后将这个“内情向量”相关信息存储在符号表中。数组定义后位置就是固定的,因此其首地址可以在编译阶段得到。当编译器到达代码生成的各阶段时,每次遇到数组名这个标识符,编译器都会从符号表中取出这个数组的首地址,然后用这个地址来替代数组名,例如,假设数组a起始地址是0×8048000,则a[1]就会被编译器转化成*(0×8048000+1),因此在生成的汇编代码中,数组名已经完全被转化成一个常量,一个固定的数(地址)。

但是,对于指针p,它是一个变量,其值存储在地址&p中,这个值在编译时是不能得到的。因为是变量,所以指针可以作为表达式中的左值操作,如++或--,而被认为是常量的数组名却不可以,正如你可以骑走一辆自行车,但是不能骑走一棵树。另外,C语言把数组下标改写成指针偏移量的根本原因是指针和偏移量是底层硬件所使用的基本模型。


第三,对数组的引用,如a[i],或*(a+1),需要访存一次;而对指针的引用,如*(p+1),需要访存两次。

如果理解了第二条的解释,这个应该就不难理解。因为a被认为是常数,所以取*(a+1)的值只需将a所表示的常数加1,然后从得到的地址里访存取一次即可。而对于指针,需要先从&p这个地址里把p的值取出来,然后加1,再从得到的地址里访存取一次,一共需要两次访存。

第四,假设a是一个数组名,而p是一个指针,当你使用 a 和 &a 时,得到值是一样的,都是数组的起始地址。而使用 p 和 &p 时,得到的值是不一样的, p 表示指针 p 所指向的地址,而 &p 表示 p 这个变量的地址。再假设


  1. p = a;

则 p 就表示数组a的起始地址,而&p是存储数组a的起始地址的那个地址。 这是因为编译器把a当成数组首地址,而&a当作数组第一个元素的地址,因此得到的值是一样的。

另外,sizeof(a)得到的是a所表示的数组的大小,而sizeof(p)得到的是指针的大小


转自:http://www.diybl.com/course/3_program/c/c_js/20111003/561447.html

www.diybl.com    时间 : 2011-10-03  作者:网络   编辑:hawk


数组名和指针变量都不可做++或--运算吗? 

检举|2012-03-30 10:48 雨明yzs | 分类:C/C++ | 浏览97次

下载知道APP,提问优先解答!

方式一:扫描二维码下载

建议:可使用微信的“扫一扫”功能扫描下载

方式二:短信免费下载

下载链接将通过短信免费下发到您的手机

发送短信

 

检举| 2012-03-30 10:57 提问者采纳
数组名不可以,指针可以。这就是指针和数组的区别。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值