c语言学习零碎整理(7):数组名是指针吗?

今天在csdn的c版看到了这样的一个帖子:http://community.csdn.net/Expert/topic/4264/4264741.xml?temp=.8964502 问的是数组和指针的区别.但最后引出的却是"数组名是指针吗?"这样一个问题.

其中megaboy(飞天御剑流之杀神一刀斩) 的回答与众不同,按他对数组名的理解:数组名是一个符号地址常量,这个解释确实可以解释一些现象,但还有很多不能用这个来解释的问题.

比如我在那个帖子里提到的两个程序:

1,include<stdio.h>
main()
{
int a[]={1,2,3};
int *p;
p=a;
printf("%d/n",p);
return 0;
}一个符号地址常量怎么可以对一个指针赋值呢?

2,又比如,printf的参数要求是一个指针,按megaboy的说法下面的程序肯定不成立.

#include<stdio.h>
main()
{
char a[]="wayne";
printf(a);
return 0;
}但结果是打印出wayne

晚上迎接新生回来以后,查了一下<<c++ primer 第三版>>和<<c++程序设计语言 特别版>>.前一本书上没有提太多这方面的东西,在7.9.2节只有一句话提到:"不带下标操作符的数组名会被解释成指向首元素的指针".后一本讲的多一点,在5.3节:"到数组的指针"中把这个问题大致讲了一下:"一个数组的名字能够被用作到它的开始元素的指针.
如 int v[]={1,2,3,4};
int *p1=v;//指向开始元素(隐式转换)  隐式地从int [ ] 转换到int *
从数组名到这个数组的开始元素的指针的隐式转换,在c风格代码的函数调用中广泛使用."      

至于到底是怎么转换地,我想没有必要了解的那么多.          

所以我还是认为"不带下标操作符的数组名会被解释成指向首元素的指针".这样好理解.但是数组名是不能被修改的,它是一个常量,不能进行任何赋值或加减的运算.

 2005.11.26 更正:
今天又认真地看了一遍K&C中关于指针和数组的章节,感到自己以前的理解是有偏差的。
我现在的理解是:
1。数组名所代表的是该数组最开始的一个元素的地址。
2。指针是一种保存变量地址的变量。
3。数组名和指针之间有一个不同之处。指针是一个变量,因此,在C语言中,语句pa=a和pa++都是合法的。但数组名不是变量,因此,类似于a=pa和a++形式的语句是非法的。
以上均抄自K&C。以前看书太不仔细了。如果从汇编的角度看的话应该更容易理解一些。
至于<<c++程序设计语言 特别版>>中提到的隐式转换,应该是把数组第一个元素的地址送到指针所在的内存空间中,即指针的值为这个地址。
同时我觉得简单地理解为"不带下标操作符的数组名会
被解释成指向首元素的指针"也没有什么错误。但要注意,数组名绝对不是指针。

2005.12.10 补充:

在一个blog上看到一篇文章,也是讨论数组名的(http://blog.csdn.net/soloist/archive/2004/11/03/164625.aspx)

觉得写得不错,所以写一下自己现在对这篇文章的一些认识,就算是对自己写的东西的一个补充吧。现在看自己前面写的,觉得以前的理解确实比较浅薄。学无止境啊,学习ing

下面引用一下soloist的文章(加粗的是我自己的一些试验和理解):

C/C++中的数组名是个很奇怪的东西,它到底代表什么呢? 

对于char array[n](n是一个常数),大概有这么几种语义:

<1> char* const(注意不是const char*)   <2> char [n]

举例如下(WIN2000 PRO平台,VC.NET 7.1下编译)

<1>  char p = array; //array表示char constp得到的是数组的首地址

size_t size = sizeof(char [n]); // size等于n

/**********sizeof(char [n])就相当于sizeof(array)*********/

<2>     char (*p)[n] = &array; // array表示char [n]

// p得到的仍然是数组的首地址

char (*q)[n] = array;  // 编译错误  

/**********因为q的类型是char (*)[n],而array的类型是char*  ************/

char (*r)[n] = (char (*)[n])array; // r得到的是array数组的首地址

/*********************我的试验和理解********************************

#include<stdio.h>

enum{n=12};

main()

{

char array[n];

char (*p)[n] = &array;//这里,&array[0]等价于&array

printf(“%d/n%d/n”,sizeof(*p),sizeof(p)); //结果为12,4

return 0;

}

语句char (*p)[n] = &array;声明了p一个指向字符数组的指针,这个数组的大小和array一样。所以sizeof(*p)sizeof(array)的值相等。注意:在这个程序中,数组array*p都只是被声明,并没有被分配内存。

我又试了一下,发现sizeof(array)sizeof( *(&array) )相等。这就可以更好地理解上面的程序了。上面的程序和sizeof( *(&array) )相比,只是多了一个变量p罢了。p的地址为&array,那么*p就是array了。所以sizeof(*p)就和sizeof(array)的值相等了。

<3> char (&p)[n] = array;  // array表示char [n]

这个语句当时让我有些迷惑,后来在别人的指点下,才明白&在这里原来是c++中的引用(c++学的不多,放在这里就更让我不懂了)。在c中编译不能通过。这个语句声明p是数组array的一个引用。所以sizeof(p)=n.

那篇文章还讨论了不少,但基本上都是以前面的为基础。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值