第一章 什么是数组名?----一个让你吃惊的事实!

 

数组是指针的基础,多数人就是从数组的学习开始指针的旅程的。下面我节选一些在各种论坛和文章里经常见到的关于数组的文字:
“一维数组是一级指针”
“二维数组是二级指针”
“数组名可以作为指针使用”
“数组名就是..........的常量指针”
“数组名就是..........的指针常量”
..................................
这些文字看起来非常熟悉吧?类似的文字还有许多,或许你就是经常说这些话的人呢。不过非常遗憾,这些文字都是错误的,实际上数组名永远都不会是指针!这个结论也许会让你震惊,但它的确是事实。数组名、指针、地址这几个概念虽然是基础中的基础,但它们恰恰是被混淆和滥用得最多的概念,把数组名说成指针,是一个概念性的错误,实质是混淆了指针与地址两个概念的本质。俗话说得好:浅水淹死人。因此,在讨论数组之前,有必要先回过头来澄清一下什么是指针,什么是地址,什么是数组名。

        指针是C语言具有低级语言特征的最直接的证据。在汇编语言里面,指针的概念随处可见。比如SP,SP寄存器又叫堆栈指针,它的值是地址,由于SP保存的是地址,并且SP的值是不断变化的,因此可以看作一个变量,而且是一个地址变量。地址也是C语言指针的值,C语言的指针跟SP这样的寄存器虽然不完全一样,但原理却是相通的。C语言的指针也是一种地址变量,C89明确规定,指针是一个保存对象地址的变量。这里要注意的是,指针跟地址概念的不同,指针是一种地址变量,通常也叫指针变量,统称指针。而地址则是地址变量的值。

        看到这里,也许你会觉得,这么简单的东西还用你来说吗?的确,对于p与&p来说,99%的人都能在0.1秒内脱口而出谁是指针,谁是地址,但是,又有多少人在使用指针的过程中能够始终如一毫不动摇地遵循这两个概念呢?不少人使用指针的时候就会自觉或不自觉地把指针和地址两个概念混淆得一塌糊涂了,数组名的滥用就是一个活生生的例子。这一点甚至连一些经典著作也没能避免。

        不过也不能全怪你自己,笔者认为某些国内教材应该承担最大的责任。这些教材一开始就没有给读者好好地分清指针与地址的区别,相反还在讲述的过程中有意无意地混用这两个概念。更有甚者,甚至在书中明言指针就是地址!说这话的家伙最应该在C语言这个地图上抹掉,呵呵。两个月前我在购书中心随手翻开了某个作者主编的一本被冠以国家“十五”规划重点研究项目的书,书里就是这么写的。当时笔者就感慨:不知道又要有多少人的思想被这家伙“**”了。

        实际上,地址这个东西,本来就是一种基本数据类型,本应该在介绍整数、浮点、字符等基本类型的时候把地址显式地放在一起讨论,这样在后面介绍指针与数组的时候就能避免许多误解。可惜不少教材或者根本没有谈及,或者就算提起这个类型也用了指针类型这个字眼。这就错了,指针不是类型,真正的类型是地址,指针只是存储地址这种数据类型的变量!打个比方,对于
int i=10;
10是整数,而i是存储整数的变量,指针就好比这个i,地址就好比那个10。
指针能够进行加减法,原因并不是因为它是指针,加减法则不是属于指针这种变量的,而是地址这种数据类型的本能,正是因为地址具有加减的能力,所以才使指针作为存放地址的变量能够进行加减运算。 这跟整数变量因为整数能够进行加减乘除因而它也能进行加减乘除一个道理。


        那么数组名又应该如何理解呢?用来存放数组的区域是一块在栈中静态分配的内存(非static),而数组名是这块内存的代表,它被定义为这块内存的首地址。
这就说明了数组名是一个地址,而且,还是一个不可修改的常量,完整地说,就是一个地址常量。数组名跟枚举常量类似,都属于符号常量。数组名这个符号,就代表了那块内存的首地址。注意了!不是数组名这个符号的值是那块内存的首地址,而是数组名这个符号本身就代表了首地址这个地址值,它就是这个地址,这就是数组名属于符号常量的意义所在。由于数组名是一种符号常量,因此它是一个右值,而指针,作为变量,却是一个左值,一个右值永远都不会是左值,那么,数组名永远都不会是指针! 不管什么话,只要说数组名是一个指针的,都是错误的!就象把刚才int i=10例子中的10说成是整数变量一样,在最基本的立足点上就已经完错了。

        总之要牢牢记住,数组名是一个地址,一个符号地址常量,不是一个变量,更不是一个作为变量的指针!

        在数组名并非指针这个问题上,通常会产生两种疑问:
1。作为形参的数组,不是会被转换为指针吗?
2。如果形参是一个指针,数组名可以作为实参传递给那个指针,难道不是说明了数组名是一个指针吗?

        首先,C语言之所以把作为形参的数组看作指针,并非因为数组名可以转换为指针,而是因为当初ANSI委员会制定标准的时候,从C程序的执行效率出发,不主张参数传递时复制整个数组,而是传递数组的首地址,由被调函数根据这个首地址处理数组中的内容。那么谁能承担这种“转换”呢?这个主体必须具有地址数据类型,同时应该是一个变量,满足这两个条件的,非指针莫属了。要注意的是,这种“转换”只是一种逻辑看法上的转换,实际当中并没有发生这个过程,没有任何数组实体被转换为指针实体。另一方面,大家不要被“转换”这个字眼给蒙蔽了,转换并不意味着相同,实际上,正是因为不相同才会有转换,相同的话还转来干吗?这好比现在社会上有不少人“变性”,一个男人可以“转换”为一个女人,那是不是应该认为男人跟女人是相同的?这不是笑话么。

        第二,函数参数传递的过程,本质上是一种赋值过程。C89对函数调用是这样规定的:函数调用由一个后缀表达式(称为函数标志符,function designator)后跟由圆括号括起来的赋值表达式列表组成,在调用函数之前,函数的每个实际参数将被复制,所有的实际参数严格地按值传递。因此,形参实际上所期望得到的东西,并不是实参本身,而是实参的值或者实参所代表的值!举个例来说,对于一个函数声明:

void fun(int i);

我们可以用一个整数变量int n作实参来调用fun,就是fun(n);当然,也正如大家所熟悉的那样,可以用一个整数常量例如10来做实参,就是fun(10);那么,按照第二个疑问的看法,由于形参是一个整数变量,而10可以作为实参传递给i,岂不就说明10是一个整数变量吗?这显然是谬误。实际上,对于形参i来说,用来声明i的类型说明符int,所起的作用是用来说明需要传递给i一个整数,并非要求实参也是一个整数变量,i真正所期望的,只是一个整数,仅此而已,至于实参是什么,跟i没有任何关系,它才不管呢,只要能正确给i传递一个整数就OK了。当形参是指针的时候,所发生的事情跟这个是相同的。指针形参并没有要求实参也是一个指针,它需要的是一个地址,谁能给予它一个地址?显然指针、地址常量和符号地址常量都能满足这个要求,而数组名作为符号地址常量正是指针形参所需要的地址,这个过程就跟把一个整数赋值给一个整数变量一样简单!

        在后面的章节中,笔者将严格地使用地址这一概念,该是地址时就用地址,该是指针时就用指针,以免象其它教材那样给读者一个错误的暗示。

---------------------------------------------------------------------------------------------------------------------------------

---------------------------------------转载:没油的猪的系列文章

C语言小知识(数组名与指针) 一、指针与数组名 1、数组名是数组的首元素地址 这里有两个例外 (一)、sizeof (数组名),这里的数组名是表示整个数组的,计算的是整个数组的大小,单位是字节 (二)、&取地址数组名,这里的数组名也表示整个数组,取出的是数组的地址 除上面两种特殊情况外,所有的数组名都是数组首元素地址 ... 阅读详情

相关推荐

指针名当数组名使用

//输入输出数组 #include <bits/stdc++.h> using namespace std; void f(int *p1) { int i; for(i=0;i<5;i++) { if(i!=4) cout<<*p1<<" "; else cout<<*p1<<endl; p1++; }

c 1530

c语言中的数组名代表的意义

数组名是数组的首地址,就是数组中的第一个元素的地址,是常量。常量是不能值在=的左边的。数组和指针的区别在于,指针是变量,是用来存储指向数据的地址的变量,而数组名是常量。一般情况下申明一个数组,比如char  a[10]; 之后  数组名a都是数组的首地址,是一个地址常量。但是在函数申明的形参列表中除外,比如: int  fo(char []); 在这种情况下的申明与 int  fo(char

u013634862的专栏 1万+

图形学基础|球谐光照(Spherical Harmonics Lighting)

球谐光照(Spherical Harmonics Lighting) 文章目录球谐光照(Spherical Harmonics Lighting)一、前言二、球谐函数2.1 基函数2.2 投影与重建2.3 应用三、漫反射环境光3.1 IrradianceMap3.2 数学推导3.3 实践参考博文 一、前言 在学习图形渲染的过程中,一直對球谐函数(球谐光照)有一点了解,但没有亲手实现过。 关于球谐函数的数学概念是比较复杂的,笔者也实在无法完全理解,这篇文章只能从做东西的角度来说,公式是如何和代码进行对应的。

【黑键】 1万+

c语言 数组名本质为指针常量,以及数组名在哪个区存放,数组空间在哪开辟

在ubuntu环境下c语言中 数组名本质是常量指针,代表首元素地址。数组首元素地址和数组首地址有着相同的地址编号。

Zheng_Emperor的博客 2816

STM32+ESP8266接入OneNet的MQTT嵌入式实现

MQTT是一种轻量级发布/订阅模式的消息传输协议,广泛应用于资源受限的物联网终端设备通信。其基于TCP/IP栈构建,具备低带宽占用、小代码体积和高可靠性等技术优势,特别适合STM32等MCU与Wi-Fi模组协同工作的边缘节点场景。在实际工程中,需结合AT指令集控制ESP8266完成Wi-Fi连接、TCP建链及MQTT会话管理,并通过环形缓冲区、空闲中断检测等机制保障UART异步通信稳定性。本文围绕STM32F103与ESP8266硬件协同、OneNet平台对接、JSON消息解析与OLED状态反馈等关键环节,

yhn456789的博客 1036

QT-使用ECharts显示地图,还有更多惊艳的图表等待你的使用

QT-使用ECharts显示地图前言一、使用步骤1.下载示例2. QT使用HTML文件配置3.使用HTML文件4. 数据交互及自适应总结注意:这个地图是百度的在线地图,需要百度API密钥和在联网的状态下使用。离线使用图表 前言 我上文QT图表chart-饼状图,使用qt自带的图表库charts来显示图表,实现数据可视化,但是QT自带的图表库显示效果并不佳,通俗说,就是不好看。 然而,有这么一个开源图表库,图表种类极多,并且效果良好,能够实现具有很好的视觉冲击的数据可视化。 它就是Apache ECharts

博咯的博客 4898

什么是数组名?----一个让你吃惊的事实!

http://blog.youkuaiyun.com/megaboy/archive/2005/09/17/482782.aspx数组是指针的基础,多数人就是从数组的学习开始指针的旅程的。下面我节选一些在各种论坛和文章里经常见到的关于数组的文字:“一维数组是一级指针”“二维数组是二级指针”“数组名可以作为指针使用”“数组名就是..........的常量指针”“数组名就是........

1431

ROBOGUIDE教程:FANUC机器人X型焊枪气动点焊焊接

FANUC机器人X型焊枪气动点焊焊接虚拟仿真实现方法。

IndRobSim 4386

数组名?----一个让你吃惊的事实【转】

第一章 什么是数组名?----一个让你吃惊的事实! 收藏         数组是指针的基础,多数人就是从数组的学习开始指针的旅程的。下面我节选一些在各种论坛和文章里经常见到的关于数组的文字:“一维数组是一级指针”“二维数组是二级指针”“数组名可以作为指针使用”“数组名就是..........的常量指针”“数组名就是.

Vange的专栏 809

Ubuntu 22.04 局域网安装GitLab

下面直接给你一份。

u013250861的博客 667

高级数据库--作业及答案

中科大金培权老师的高级数据库课程作业及答案

一杯水果茶!足矣~ 1658

(转)什么是数组名?----一个让你吃惊的事实!

 数组是指针的基础,多数人就是从数组的学习开始指针的旅程的。下面我节选一些在各种论坛和文章里经常见到的关于数组的文字:“一维数组是一级指针”“二维数组是二级指针”“数组名可以作为指针使用”“数组名就是..........的常量指针”“数组名就是..........的指针常量”..................................这些文字看起来非常熟悉吧?类似的文字还有许多,或许你就是

让疑问和无知见鬼去吧! 644

2026年全国青少年信息素养大赛算法应用主题赛(C++赛项初赛模拟卷1及答案解析)

2026年全国青少年信息素养大赛算法应用主题赛(C++赛项初赛模拟卷1及答案解析)

王老师青少年编程 2023

什么是数组名?----一个让你吃惊的事实!(

数组是指针的基础,多数人就是从数组的学习开始指针的旅程的。下面我节选一些在各种论坛和文章里经常见到的关于数组的文字:“一维数组是一级指针” “二维数组是二级指针” “数组名可以作为指针使用” “数组名就是..........的常量指针” “数组名就是..........的指针常量” .................................. 这些文字看起来非常

314

【Proteus仿真】点亮小灯系列仿真——小灯闪烁/流水灯/交通灯

本文介绍了基于AT89C51单片机的LED控制案例,共包含5个实例:1)单个LED闪烁;2)共阳极流水灯;3)共阴极流水灯;4)花样流水灯;5)交通灯模拟。每个案例详细说明了电路原理图、接线方式和控制程序实现,其中重点讲解了PWM调光原理及其在LED控制中的应用。案例由简至繁,从基础I/O控制到复杂花样显示,最后实现交通灯逻辑控制,展示了单片机在LED控制中的典型应用方法。文中提供了完整的源代码,便于读者理解和实践。

XU157303764的博客 1883

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

[C Tips] 数组名一定代表指向数组第一个元素的指针--------吗?

无数的教科书都几乎没有严肃认真的面对这个问题。数组名就一定代表指向数组第一个元素的指针吗?猜猜下面的代码输出是怎么样的:Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->char ga[] = "abcdefghijklm";void my

1300

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

第二章 再一次吃惊----数组的数组与多维数组的区别

原文:http://blog.youkuaiyun.com/megaboy/article/details/482781 看见这个题目,也许有些人就会嘀咕了:难道两者不是一样的吗?C语言的多维数组不就是数组的数组吗?不!两者是有区别的,而且还不小呢。首先看看两者的共同点: 1。内存映象一样。 2。数组引用方式一样,都是“数组名[下标][下标]........”。 3。数组名都是数组的首地址,都是一

永久指针 851

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

第二章 再一次吃惊----数组的数组与多维数组的区别

        看见这个题目,也许有些人就会嘀咕了:难道两者不是一样的吗?C语言的多维数组不就是数组的数组吗?不!两者是有区别的,而且还不小呢。首先看看两者的共同点:1。内存映象一样。2。数组引用方式一样,都是“数组名[下标][下标]........”。3。数组名都是数组的首地址,都是一个符号地址常量、一个右值。        由于两者的共同点主要反映在外部表现形式上,因此,从外部看来,数组的数组

7663

第二章 再一次吃惊!----数组的数组与多维数组的区别

       看见这个题目,也许有些人就会嘀咕了:难道两者不是一样的吗?C语言的多维数组不就是数组的数组吗?不!两者是有区别的,而且还不小呢。首先看看两者的共同点: 1。内存映象一样。 2。数组引用方式一样,都是“数组名[下标][下标]........”。 3。数组名都是数组的首地址,都是一个符号地址常量、一个右值。         由于两者的共同点主要反映在外部表现形式上,因此,从外部看...

weixin_34038293的博客 73
上一篇: 苹果是否改变我们的生活
下一篇: 第二章 再一次吃惊----数组的数组与多维数组的区别
cubelee
博客等级 码龄15年 4粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值