指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用。于是乎,很多程序设计者就被搞糊涂了。
魔幻数组名
请看程序(本文程序在WIN32平台下编译):

#include <iostream>

using namespace std;

int main()

{

  char str[10];

  char* pStr = str;

  cout << "sizeof(str): \t" << sizeof(str) << endl;

  cout << "sizeof(pStr): \t" << sizeof(pStr) << endl;

  system("pause");

  return 0;

}

1、数组名不是指针
我们先来推翻"数组名就是指针"的说法,用反证法。
证明 数组名不是指针
假设:数组名是指针;
则:pStr和str都是指针;
因为:在WIN32平台下,指针长度为4;
所以:sizeof(str)和sizeof(pStr)的输出都应该为4;
实际情况是:

所以:假设不成立,数组名不是指针
2、数组名神似指针
上面我们已经证明了数组名的确不是指针,但是我们再看看程序的这一:char* pStr = str;。该行程序将数组名直接赋值给指针,这显得数组名又的确是个指针!
我们还可以发现数组名显得像指针的例子:

#include <iostream>
using std::cout;
using std::endl;
int main()
{
char str1[10] = "I love U.";
char str2[10]; strcpy(str2, str1); cout << "string array 1: " << str1 << endl;
cout << "string array 2: " << str2 << endl; system("pause");
return 0;
}

标准C库函数strcpy的函数原形中能接纳的两个参数都为char型指针,而我们在调用中传给它的却是两个数组名!

函数输出:

数组名再一次显得像指针!
既然数组名不是指针,而为什么到处都把数组名当指针用?

揭密数组名
现在到揭露数组名本质的时候了,先给出三个结论:
(1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组;
(2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量;
(3)指向数组的指针则是另外一种变量类型(在WIN32平台下,长度为4),仅仅意味着数组的存放地址!
1、数组名指代一种数据结构:数组
现在可以解释为什么第1个程序的这一行:sizeof(str);的输出为10的问题,根据结论1,数组名str的内涵为一种数据结构,即一个长度为10的char型数组,所以sizeof(str)的结果为这个数据结构占据的内存大小:10字节。
再看:

1.int intArray[10];
2. cout << sizeof(intArray) ;

第2行的输出结果为40(整型数组占据的内存空间大小)。
如果C/C++程序可以这样写:

1. int[10] intArray;
2. cout << sizeof(intArray) ;

我们就都明白了,intArray定义为int[10]这种数据结构的一个实例,可惜啊,C/C++目前并不支持这种定义方式。
2、数组名可作为指针常量
根据结论2,数组名可以转换为指向其指代实体的指针,所以程序1中的第5行数组名直接赋值给指针,程序2第7行直接将数组名作为指针形参都可成立。
下面的程序成立吗?

1. int intArray[10];
2. intArray++;

读者可以编译之,发现编译出错。原因在于,虽然数组名可以转换为指向其指代实体的指针,但是它只能被看作一个指针常量,不能被修改。 
而指针,不管是指向结构体、数组还是基本数据类型的指针,都不包含原始数据结构的内涵,在WIN32平台下,sizeof操作的结果都是4。
顺 便纠正一下许多程序员的另一个误解。许多程序员以为sizeof是一个函数,而实际上,它是一个操作符,不过其使用方式看起来的确太像一个函数了。语句 sizeof(int)就可以说明sizeof的确不是一个函数,因为函数接纳形参(一个变量),世界上没有一个C/C++函数接纳一个数据类型(如 int)为"形参"。
3、数组名可能失去其数据结构内涵 
到这里似乎数组名魔幻问题已经宣告圆满解决,但是平静的湖面上却再次掀起波浪。请看下面一段程序:

#include <iostream>
using std::cout;
using std::endl;
void arrayTest(char str[])
{
cout << "sizeof(str):" << sizeof(str) << endl;
}
int main()
{
char str1[10] = "I love U.";
arrayTest(str1); system("pause");
return 0;
} 程序的输出结果为:

一个可怕的数字,前面已经提到其为指针的长度!

结论1指出,数组名内涵为数组这种数据结构,在arrayTest函数体内,str1是数组名,那为什么sizeof的结果却是指针的长度?这是因为:

(1)数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;

(2)很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

所以,数组名作为函数形参时,其全面沦落为一个普通指针!它的贵族身份被剥夺,成了一个地地道道的只拥有4个字节的平民。

以上就是结论4。

数组名和指针的深入理解(C++)的更多相关文章

  1. 对于C语言中数组名是指针的理解

    我们都知道,c语言中数组名是一个指针,比如下面这段代码 #include<iostream>using namespace std;int main(){ int a[4]={1,2,3, ...

  2. C/C++数组名与指针区别深入探索(转载)

    转载自: C/C++数组名与指针区别深入探索 引言 指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用.于是乎,很多程序设计者就被搞糊涂了.而许多的大学老师, ...

  3. C/C++——C语言数组名与指针

    版权声明:原创文章,转载请注明出处. 1. 一维数组名与指针 对于一维数组来说,数组名就是指向该数组首地址的指针,对于: ]; array就是该数组的首地址,如果我们想定义一个指向该数组的指针,我们可 ...

  4. C/C++数组名与指针的区别详解

    1.数组名不是指针我们看下面的示例: #include <iostream> int main() { ]; char *pStr = str; cout << sizeof( ...

  5. c/c++数组名和指针区别深入探索

    指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用.于是乎,很多程序设计者就被搞糊涂了.而许多的大学老师,他们在C语言的教学过程中也错误得给学生讲解:&quo ...

  6. CPP-基础:C/C++数组名与指针的区别

    2005-08-23 08:36 来源:天极网 作者:宋宝华 责任编辑:方舟·yesky 引言 指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用.于是乎,很 ...

  7. 【转】C语言中数组名和指针的区别

    注:本文转自http://www.cnblogs.com/furaibo/archive/2010/03/19/1689710.html 魔幻数组名 请看程序(本文程序在WIN32平台下编译): #i ...

  8. 放弃"指针常量"这种不严谨的中文描述!深度理解数组名、指针常量

    ques1: 数组名完全等价于指针常量吗? int array[10] = { 10,11,12,13,14,15 }; printf("sizeof(array)= %d \n" ...

  9. C和指针 第六章 数组名与指针

    指针的算术运算符是指针和数组之间的一种关联,但不是唯一关联: 可以使用数组名作为指向数组第一个元素的指针,但是不可以给数组名赋新的值. //如下声明a int a[10]; //用a作为指向数组第一个 ...

随机推荐

  1. C++ string实现原理

    C++程序员编码过程中经常会使用string(wstring)类,你是否思考过它的内部实现细节.比如这个类的迭代器是如何实现的?对象占多少字节的内存空间?内部有没有虚函数?内存是如何分配的?构造和析构 ...

  2. 运用JavaScript构建你的第一个Metro式应用程序(onWindows 8)(三)

    原文 http://blog.csdn.net/zhangxin09/article/details/6793593 这是<运用 JavaScript构建你的第一个Metro式应用程序>系 ...

  3. JavaEE Tutorials (17) - Java消息服务示例

    17.1JMS示例概述23317.2编写简单的JMS应用233 17.2.1启动JMS提供者234 17.2.2创建JMS受管理对象234 17.2.3构建所有简单示例235 17.2.4发送消息23 ...

  4. [虚拟化/云][全栈demo] 为qemu增加一个PCI的watchdog外设(六)

    目的: 1. 为我们自己的watchdog写一个驱动 步骤: 通过之前的介绍,我们很容易猜想到写我们基于PCI的watchdog驱动,可以分2个步骤. 1. 探测加载PCI设备 这部分代码跟我们的设备 ...

  5. SRM 584 div2

    早早地水完了三道题,pt1000用的是dfs,开始做的时候误认为复杂度最多就O(2^25),结果被一组O(2*3^16)的数据接近1e8给cha了.继续努力. pt250:求两个串的前缀组成的不同串数 ...

  6. JavaScript之JS实现动画效果

    在前面的随笔中介绍了如何用DOM技术修改文档的央样式信息,用JavaScript添加样式信息可以节约我们的时间和精力,但总的来说,CSS仍是完成这类任务的最佳工具.但是有一个应用领域是目前的CSS无能 ...

  7. This project references NuGet package(s) that are missing on this computer.

    Install Nuget. Right click on the solution and select "Enable NuGet Package Restore". Clic ...

  8. Asp.Net Memcached安装配置使用、安全性

    Memcached安装配置使用  一,准备        你需要有一下软件:       VS.NET(05/08)       SQLSERVER       memcached服务器端以及客户端类 ...

  9. [C#参考]锁定lock

    Lock关键字解释: lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁. 下面的示例包含一个 lock 语句. lock 关键字可确保当一个线程位于代码的临界区 ...

  10. Labview学习之远程控制VI

    Labview学习之远程控制VI        从LabVIEW 6.1开始,LabVIEW集成了Remote Panels技术,允许用户直接在客户端计算机上打开并操作位于服务器端计算机上的VI的前面 ...