指针数组与数组指针、指针常量与常量指针解析

  指针数组、数组指针、指针常量、常量指针,这些名词很容易混淆经常会困惑着许多的C语言初学者。本文将用尽可能简单的方式介绍清楚二者的异同。

指针数组与数组指针、指针常量与常量指针解析

  what???指针数组与数组指针这俩货难道不是一回事吗???
  不不不其实这俩货差别大着呢。通过名字来区分指针数组是数组,而数组指针是指针,记忆诀窍就是看名字的最后两个字。他们两在定义的时候差不多就是下面这么个情况。
在这里插入图片描述
  为什么int *pa[5]是指针数组而int (*pb)[5]又是数组指针呢?这个是根据C语言的运算符的优先级来决定的1。因为下标运算符优先于取值运算符所以 int *pa[5]是一个数组,又因为当9()和[]同时出现是按从左到右依次运算,所以 int (*pb)[5] 是一个指针,然后再是存放在数组中。

一、指针数组

  指针数组的本质是一个数组,不过这个数组和别的数组有一些不同的是这个数组里面的每一个元素都是指针的数组。同时还需要注意的是指针数组里面的每一个元素的变量类型都和指针的类型一致,也就是说整形的指针数组里面的每一个元素都是整形指针。指针数组的定义方式如下:

#include <stdio.h>
int main()
{
	int a = 1,b = 2,c = 3,d = 4;
	int *e[]={&a,&b,&c,&d};
	int i;
	for(i=0;i<4;i++)
	{
		printf("%d",*e[i]);
	}
	return 0;
}

【运行结果】
在这里插入图片描述
  如果我们不这样定义,按照普通数组的定义方法来定义的话可以通过编译,但是运行的时候就会出错。这是因为指针数组里面的每一个元素存放的都应该的地址。如果我们存储非地址的值虽然可以通过编译,但是不能得到我们想要的结果。

/*#include <stdio.h>
int main()
{
	int *e[]={1,2,3,4};
	int i;
	for(i=0;i<4;i++)
	{
		printf("%d",*e[i]);
	}
	return 0;
} */这是错误示范

【运行结果】
实际效果可能会因不同编译器产生差异
  另外还需要注意的是,我们在使用指针数组存放指向字符串的指针在读取的时候和指向整形变量略有不同,上面我们在读取指向整形变量的指针数组的时候输出是使用的 printf(“%d”,*e[i]); 而我们在读取指向字符串的地址的指针数组的时候不能这样,因为我们需要读出整个字符串所以不需要再在指针数组前面加上取值运算符。详情见下面是指向字符串的指针数组的示例。

#include <stdio.h>
int main()
{
	char *pa[2]=
	{
		"hello,world!",
		"hello,c!",
	};
	int i;
	for(i=0;i<2;i++)
	{
		printf("%s\n",pa[i]);
	}
	return 0;
 } 

【运行结果】
在这里插入图片描述

二、数组指针

  通过前面的介绍我们已经知道了数组指针是一个指针,这个指针是一个指向数组的指针。.既然提到了数组指针是一个指向数组的指针数组的指针,可能有的小伙伴就要说了这个不是在前面学习指针的时候就学了嘛,其实这两者是不一样的。两者的程序都列在了下面,具体的我们可以来比对一下进行讲解。

程序一:指针数组程序

#include <stdio.h>
int main()
{
	int temp[]={1,2,3,4,5};
	int (*pt)[5]=&temp;
	int i;
	for(i=0;i<5;i++)
	{
		printf("%d\t",*(*pt+i));
	}
	return 0;
}

【运行结果】
在这里插入图片描述
程序二:用指针遍历数组的程序

#include <stdio.h>
int main()
{
	int a[]={1,2,3,4,5};
	int *pa=a;
	int i;
	for(i=0;i<5;i++)
	{
		printf("%d\t",*(pa+i));
	}
	return 0;
}

【运行结果】
在这里插入图片描述
  通过上面的两个程序我们发现,同样是读取数组却有不同的方法。其实第二种方法只能叫做使用指针遍历数组,因为第二个程序的指针其实指向的是数组的第一个元素的地址2,所以我们在读取的时候是使用的 *(pa+1) 。而第一个程序才是真正意义上的数组指针。
  如果看完本文有疑问或者好的建议与欢迎在下方留言评论。

三、指针常量

  int* const a
  指针常量的本质是一个常量,使用指针修饰它。指针常量的值是指针,这个值因为是常量,所以不能被赋值。

四、常量指针

  cconst int* aint const * a等同
  常量指针的本质是一个指针,但是他指向的是一个常量。常量指针可以指向不同的常量,但由于指向的值是常量,所以指向地址的值不可以被修改。

五、巧记

  看屁股,屁股为实质。
  屁股是数组,则实际是数组,数组的里面是指针。屁股是指针,则实际是指针,指向了一个数组。
  屁股是常量,则常量可以被修改。屁股是指针,则指向的地址可以被修改。


  1. 关于C语言运算符的优先级可参考此文运算符的优先级和结合性↩︎

  2. 因为数组名等于数组的第一个元素的地址等于数组的地址。所以我们在赋值的时候只写了数组名,但是其实他是指向的数组的第一个元素的地址。 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

127.0.0.1/24

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值