MENU

数组与指针,指针与const

• October 22, 2020 • Read: 2985 • 学习笔记,C++

数组与指针

我们都知道一个指针是代表的一个地址,指针,顾名思义,指向一块区域。那么数组呢?数组并不是代表一堆变量,数组其实也是一种指针,指向一个地址,一般是指向数组的首地址,也就是 a[0]的地址。
a==&a[0] a 是一个指针,指向数组 a 的首地址。
下面四种函数原型都是等价的,第一个参数均为一个地址(指针)。
若定义 int a[10];

int fun(int a[],int b);
int fun(int *a,int b);
int fun(int *,int b);
int fun(int [],int b);

可见,数组就是一个特殊的指针,所以,我们在定义指针的时候,也不需要对数组取地址,如:

int a[10];int *p=a//而不是 int p=&a;

但注意,一个数组的某个单元却是表示的一个变量,定义指针时需要对其取地址。比如定义指针 p 指向数组 a 的第三个单元。

int a[5];int p=&a[2];//如果对指针 p 赋值,则是更改 a[2]的值。

其次,[]不仅可以用于数组,也可以用于指针(数组就是一个特殊的指针),如下列代码:

int a=10;
int *p=&a;
printf("*p=%d\n",*p);
printf("p[0]=%d\n",p[0]);

两个 printf 语句将输出同样的结果,均为 10。
当然*不仅可以用于指针,也可以用于数组(数组就是一个特殊的指针,重点强调),如下列代码:

int a[5]={10};
printf("*a=%d\n",*a);
printf("a[0]=%d\n",a[0]);

显然,他们输出的结果也是相同的,均为 10,因为前面说到 a 所指向的地址就是数组 a 的首地址(a[0]的地址)。

我们一直说数组是一个指针,那么它究竟是一个什么样的指针?
数组其实是一个 const 指针,什么意思?就是一个常量指针,它的地址被定义后将不能够改变。这也是数组之间无法互相赋值的原因,如以下代码:

int a[5]={5};
int b[5]={10};
b[]=a;//Error!编译器无法通过,因为数组指针是一个常量,它的地址将无法改变,相当于int * const b;

指针与 const

指针与 const 之间会发生很多不同的情况,定义指针时,const 所在的位置不同,表达的意义也将不同。
1.指针是 const
顾名思义,就是指针是一个常量,指针本身无法被改变,数组就是一个很好的例子,它就是一个常量指针,所以我们无法对他进行更改。
如以下代码:

int a=10;
int * const p=&a;
*p=25;//通过,因为我们改变的是指针所指向地址所对应的值a,a并不是一个常量。
p++;//Error!编译器无法通过,因为指针p是一个常量(const),它所指向的地址无法被改变。

2.不能通过指针修改变量
定义方法:

int i=10;
int const *p1=&i;
const int *p2=&i;

这两种定义方法是一样的,const 的位置只有星号前和星号后的区别。
此时,我们就不能通过指针*p 去改变变量 i 的值了,以下代码编译器将无法通过:

int i=5;
const int *p=&i;
*p=25;//Error!

但我们如果对 p 进行更改,是可以通过的。

p=p+1;

3.变量是 const
如果一个变量是 const,那么我们通过指针不能够修改变量,并且变量本身在定义后也不能被赋值。
如以下代码:

const int a=5;
int *p=&a;
*p=25;//Error!通过指针改变一个const常量,存在严重安全隐患,编译器禁止
a=25;//Error!

4.非 const 可以转换为 const
当一个参数比地址还要大的时候,我们通常可以用指针将参数传入(参数非 const 类型),避免过多的字节数传入函数。
如以下代码:

void fun(int const *p);//无法通过*p改变所指向变量的值
int a=15;
const int b=10;
fun(&a);
fun(&b);

这样我们既能够保证传入 fun()函数的字节数较小,也能够保证 fun()函数外变量的安全。

const 数组

我们已知数组就是一个 const 类型的指针,那么给数组再加 const 是什么意思呢?

const int a[10]={5};

此时数组中任意单元的值将无法被改变,以下代码将无法通过编译器:

const int a[10]={5};
a[2]=1;//Error!
int *p=a;
p[2]=1;//Error!

使用场景:
为了确保数组安全,可在定义函数时将传入的数组转换为 const。

void fun(const int a[],int length);

此时,在 fun()函数中,将无法对 a[]中任意单元进行改变,确保了数组 a 中元素的安全。


编辑:Henry 2020-06-08 未经授权,严禁转载。

版权属于:字节星球/肥柴之家 (转载请联系作者授权)
原文链接:https://www.bytecho.net/archives/c1-1.html
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

Last Modified: January 16, 2021
Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment

4 Comments
  1. zizdog zizdog IP属地:山西     Android    FireFox

    纯广告,应该直接del哈哈

    1. Henry Henry     Windows 10+    Google Chrome

      @zizdog最近老是有这种广告...屏蔽了好几个关键词了,又换了一个关键词来发广告,无语。

  2. xxx公司 xxx公司 IP属地:广东     Windows 10+    FireFox

    又发现一个好站,收藏了~以后会经常光顾的 (。•ˇ‸ˇ•。)

    1. Henry Henry     iPhone    Safari

      @xxx公司人工智能评论审核:监测到广告。已抹除广告信息。