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

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

http://blog.youkuaiyun.com/megaboy/archive/2005/09/17/482782.aspx

数组是指针的基础,多数人就是从数组的学习开始指针的旅程的。下面我节选一些在各种论坛和文章里经常见到的关于数组的文字:

“一维数组是一级指针”

“二维数组是二级指针”

“数组名可以作为指针使用”

“数组名就是..........的常量指针”

“数组名就是..........的指针常量”

..................................

这些文字看起来非常熟悉吧?类似的文字还有许多,或许你就是经常说这些话的人呢。不过非常遗憾,这些文字都是错误的,实际上数组名永远都不会是指针!这个结论也许会让你震惊,但它的确是事实。数组名、指针、地址这几个概念虽然是基础中的基础,但它们恰恰是被混淆和滥用得最多的概念,把数组名说成指针,是一个概念性的错误,实质是混淆了指针与地址两个概念的本质。俗话说得好:浅水淹死人。因此,在讨论数组之前,有必要先回过头来澄清一下什么是指针,什么是地址,什么是数组名。

        指针是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了。当形参是指针的时候,所发生的事情跟这个是相同的。指针形参并没有要求实参也是一个指针,它需要的是一个地址,谁能给予它一个地址?显然指针、地址常量和符号地址常量都能满足这个要求,而数组名作为符号地址常量正是指针形参所需要的地址,这个过程就跟把一个整数赋值给一个整数变量一样简单!

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

 

37.华为路由器:loopback(本地回环)接口的作用 本地环回接口(或地址),亦称回送地址(loopback address)。 此类接口是应用最为广泛的一种虚接口,几乎在每台路由器上都会使用。常见于如下用途: 1 作为一台路由器的管理地址 系统管理员完成网络规划之后,为了方便管理,会为每一台路由器创建一个loopback 接口,并在该接口上单独指定一个IP 地址作为管理地址 ,管理员会使用该地址对路由器远程登录(telnet ),该地址实际上起到了类似设备名称一类的功能。 但是通常每台路由器上存在众多接口和地址,为何不从当中随便挑选一个呢 ? 原因如下:由于 阅读详情

相关推荐

Protege入门指南:从下载到本体构建实战

本文是Protege的入门实战指南,详细介绍了如何从官网下载安装这款由斯坦福大学开发的免费本体构建工具,并通过经典的“披萨本体”案例,系统讲解了类、属性、个体和公理四大核心要素。文章还深入解析了Protege的工作界面,并引导读者亲手创建一个简易的“公司人员组织”本体,完成从定义概念、建立关系到逻辑推理的全流程,是知识图谱与本体建模初学者的理想教程。

weixin_29093169的博客 699

C语言中“数组名”和“&数组名”

C语言中 数组名 和 &数组名 == 实验环境 == 1. 编译器:gcc 5.4.0 2. 操作系统:Ubuntu 16.04 x86_64 缘起 本以为此知识点我已熟练掌握,可是最近应用的时候还真给记混淆了。所以写篇文章加深印象。 Show me the code 废话少说,show me the code. #include <stdio.h> int ...

车子(chezi) 1万+

基于gm/id方法的折叠式共源共栅放大器设计实践

本文详细介绍了基于gm/id设计方法进行折叠式共源共栅放大器设计的完整流程。该方法通过确定晶体管的跨导效率(gm/id)作为核心设计参数,将复杂的放大器设计转化为有明确路径的优化问题。文章以设计一个增益80dB、带宽1GHz的两级放大器为例,逐步拆解了从指标分解、关键晶体管工作点选取、到实战仿真与微调的全过程,特别强调了第二级设计对稳定性的影响以及相位裕度的调试技巧。

w8x9y0z1的博客 415

C语言中数组是不是一个变量,数组在c语言中是什么

在C语言中,数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。关于C语言中数组的定义如果在参数表中,int [],实际会被转换成int *。不信你可以试试这个程序:#include void f(int b[10]){ printf("%d\n",sizeof(b...

weixin_35692051的博客 2771

BOM 数据模型设计

字段名数据类型必填说明物料编码 (Part Number)字符串是唯一标识,主键。建议包含分类前缀(如STD-GEN-CUS-物料名称 (Part Name)字符串是版本 (Revision)字符串是如AB1.0,与编码组合构成唯一实例。状态 (Status)枚举是设计中(Draft)已发布(Released)已归档(Archived)已作废(Obsoleted)类型 (Type)枚举是专用件(Custom)借用件(Borrowed)通用件(Generic)标准件(Standard)

Davina_yu的博客 1757

ARM系统控制和管理接口System Control and Management Interface

本文档描述了一个可扩展的独立于操作系统的软件接口,用于执行各种系统控制和管理任务,包括电源和性能管理。 本文档描述了系统控制和管理接口(SCMI),它是一组操作系统无关的软件接口,用于系统管理。

AI-安全-功耗 1913

数组名 和&数组名的理解

对于数组名的理解

anayi的博客 1952

5G/NR 随机接入过程学习总结

对于随机接入过程,NR与LTE之间有相同点,也有不同点,其最大的区别在于触发场景已经Msg1的处理,详情见下文。 第21章 随机接入过程 21.1 随机接入过程事件触发场景 1) 初始接入:UE从RRC_IDLE态到RRC_CONNETTED态; 2) RRC连接重建:以便UE在无线链路失败后重新建立无线连接(期间重建小区可能是UE无线链路失败的小区,也...

欢迎来到小七的博客,这里将带你深入探索5G通信的神秘世界。无论你是通信领域的专业人士还是对这一领域充满好奇心的技术爱好者,这里都有专业协议解读、通信知识普及以及有趣的Python编程内容等你发现。 7万+

数组名++

int a[10]; a++;//是无法通过编译的,a在运算中表示数组a的首地址,a++会给a重新赋值,导致数组首地址改变; int * pb; pb=a+1;//可以通过编译的,数组名a在运算表达式中表示首元素地址,a+1,表示a偏移一个int型长度(即4个字节); int b; a[0]++;//可以通过编译,a[0]是一个int型数据,a[0]++表示a[0]自身加1 ...

keepwalking111的博客 3770

1、电路分析知识全解析:从基础到实践应用

本博客全面解析电路分析知识体系,涵盖从基础的电压、电流、电阻概念到复杂的交流电路、瞬态分析和高级应用如滤波器与变压器等内容。适合电子技术专业学生和技术爱好者学习,提供详细的知识结构、学习路径、实践示例以及丰富的学习资源,包括计算机模拟工具Multisim和PSpice的使用指导。通过理论与实践结合,帮助学习者掌握电路分析的核心技能,为电子工程和电力系统等相关领域打下坚实基础。

iii12的专栏 159

专栏三:解析spatialCNV的使用

文章Spatially resolved clonal copy number alterations in benign and malignant tissue发在natur

m0_58549466的博客 1252

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

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

Liuqz2009的专栏 1279

基于HetConv与Dual策略的YOLOv8轻量化设计-CSPHet结构的优化与实现

在计算机视觉中,YOLOv8作为目标检测领域的最新版本,通过引入多种改进来提升检测精度和速度。然而,提升精度和保持实时性能往往需要更多参数与计算量。本文提出一种结合Dual思想与HetConv的新型轻量化结构,称为CSPHet。CSPHet能够在保持YOLOv8检测精度的基础上有效减少约70万参数量,实现模型的轻量化和速度的提升。HetConv(Heterogeneous Convolution)是一种混合卷积技术,通过同时使用1x1、3x3等不同大小的卷积核,来捕捉不同尺度的特征。

博客 1325

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

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

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

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

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

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

314

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

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

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

Vange的专栏 809

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

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

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

1301

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

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

永久指针 851

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

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

7663
上一篇: 指针与数组的关系
下一篇: #include iostream 和 #include iostream.h 的区别
K行天下
博客等级 码龄19年 358粉丝 19原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值