C++系列——指针和数组详细分析

1. 指针和数组在编译阶段的(本质)区别

指针:

编译器符号表指向的是指针变量的地址值,所以还要先得到指针变量所存放的地址值,然后根据该地址值取引用其所指向的对象内容,也就是间接引用其所值对象的值。

数组:

编译器符号指向的是数组的首个元素的地址,通过下标直接计算元素偏移量,从而直接得到元素的值。

int a[10];
int *ap;
ap = a;
printf(" addr of a = %p\n addr of &a = %p\n addr of &a[0] = %p\n addr of ap = %p\n addr of &ap =  %p\n", a, &a, &a[0], ap, &ap);
运行结果:


分析:说明了通过数组下标运算取元素是直接取到的(一次地址引用:根据数组首地址或加上偏移量取到数组元素),而如果通过指针的方式取数组元素,则只能通过间接的方式取到(二次地址引用:取指针所指向的地址内容+根据该地址内容取到数组元素)。


2. 指针和数组作为函数参数的区别

一维数组作为函数形参:

形式:

int foo(int *pd) //ok
int foo(int pd[]) //ok

说明:由于数组的第一维的长度不需要,所以,指针和数组的声明形式是都可行的。


多维数组作为函数形参(如2维)

形式:

int foo(int (*pm)[100]) //ok.()是必须的,不能省略,见说明2
int foo(int pm[][100]) //ok

说明:
  1. 由于除了数组的第一维以外的维度的长度都需要被指明,所以只能采用上述两种形式。
  2. 不能采用int  *pm[100]的形式,这种形式表示的是一个指针数组(数组中的100个元素都是int *类型)。在下一节中重点介绍指针数组。有没有括号的存在,就是改变了符号运算的顺序。一般来说,下标运算的优先级是高于简介引用的。所以对于有括号的情况,pm表示的是指向整型数组的指针;对于没有括号的情况,pm表示的是指针数组

3. 指针数组

形式:

int *p[100];
一个指针数组的常用方式:

char const keyword[] = {
    "do",
    "for",
    "if",
    "register",
    "return",
    "switch",
    "while",
}
#define N_KEYWORD
    (sizeof(keyword) / sizeof(keyword[0]))

说明:指针数组也就是每个数组元素指向的是一个指针,指针指向对象的内容是比较灵活的,所以每个元素的长度是可变的。这种形式的出现也是为了使得对象的内存存放更加紧凑,达到节约存储空间的目的,比如上面举得keyword指针数组的例子。与之对比,如果是用一个二维数组来存储,则会使得每个数组元素的长度都是最长字符串的长度,浪费了空间,尤其是在只有几个字符串的长度较长的情况下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值