C++之数组名和指针的区别---补充(10)《Effective C++》

有木有同学思考过为什么我们在进行数组参数传递的时候为什么不止需要传递数组或者数组指针,还需要传递一个表示数组长度值的一个数值呢?

例如这样:

#include <iostream>
using namespace std;

//int p[]或者int* p
void show(int p[], int n){
    for (int i = 0; i < n; i++){
        cout << p[i] << " ";
    }
    cout << endl;
}
int main(){
    int *p = new int[10];
    for (int i = 0; i < 10; i++){
        p[i] = i + 1;
    }
    show(p, 10);
    return 0;
}

运行结果:
这里写图片描述

为了解释这个问题,我们需要看一下如下示例:

#include <iostream>
using namespace std;

int main(){
    int a[10];
    int *p = new int[10];
    cout << sizeof(a) << endl;
    cout << sizeof(p) << endl;
    //sizeof(a)计算的是整个int数组的空间
    cout << sizeof(a) / sizeof(a[0]) << endl;
    //sizeof(p)计算的是p指针的内存空间
    cout << sizeof(p) / sizeof(p[0]) << endl;
    return 0;
}

运行结果:
这里写图片描述
在我们理解的都是数组,为什么一个数组长度为10,另一个却为1呢???
这样可以看出:数组名并不完全等价于指针,虽然它们都是通过指针访问数组。那么现在回到上上个问题。
数组在作为函数参数传递的过程中,会被自动退化为指针,因此我们在将数组或者指针作为参数传递时候,同时还需要一个表示数组长度的值。

下面我们对指针和数组的区别进行一个讲解:
1)指针变量存储的是一个地址,用来简介访问数据,一个指针变量一般占用4个字节,指针可以指向任何空间;那么数组呢?编译器根据数组元素的类型和个数在内存中开辟一段连续的内存空间,因为连续,所以经常方便通过指针访问;
2)指针和数组访问时候的区别:
在讲这个部分之前,我们先来看看一下代码:
file1.c

char p[6]="abcde";

file2.c

#include <iostream>
using namespace std;
extern char* p;

int main(){
    cout<<p[1]<<endl;
    return 0;
}

猜猜这个部分会输出什么?
这里写图片描述
意外吧!!!我们在后面将进行一个详细描述,这个问题的原因。

这里写图片描述
指针:

char *p="abcde";
char c=*p;

数组:

char a[6]="abcde";
char c=a[0];

可以看到过通过数组访问的话,数组的地址就是实际存放元素的地址,而指针呢,指针在内存空间中占开辟一个空间,用来存放指针,该内存空间一般为4个字节,有其地址,里面存放的值也是一个地址,指向数组首元素的地址。

好了,现在让我们看看上面代码的问题出在哪里:
file1.c中声明char c[]数组,在内存中开辟了一段6个字节的连续区域,file2.c中却声明为char* c指针,导致编译器从内存中取出char[]数组的前4个字节作为c的地址,所以注定做错;
如果我们考虑将file1.c中声明为数组,而file2.c中定义为指针呢?哈哈,同样有问题啦!因为file2.c中定义的如果是指针的话,则指针p内保存的是4个字节的数组元素首地址,然而file1.c中的数组如何匹配呢?会将char*指针值即数组元素首地址当做4个char字节数组进行匹配,所以同样会有问题的。

3)应该注意的地方

  • sizeof计算所占空间时的区别,对于数组,sizeof计算的是真个数组所占的空间,而sizeof指针的时候一般都是4;
  • 数组名不可以作为左值,而指针却可以作为左值进行赋值;
  • 指针可进行自增自减运算,但是数组不能;
  • 理解char*p=”abcde”和char str[]=”abcde”的区别;

参考:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242138.html

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值