玩转C语言之数组-数组指针

5 篇文章 0 订阅

数组指针

  在揭开数组指针神奇的面纱之前,我们先来探讨一下数组是否有自己特定的类型呢?

1. 数组类型

  我们知道数组是相同类型变量的有序集合。例如 int a[5] = {0};,其含义就是 5int 类型变量集合在一起由数组 a 管理。那么我想问一下,数组 a 的类型是什么呢?

  如果读者是正在C语言求学道路上的话,那么你的答案应该是 int 类型。但是我想说的是,很不好意思,这个答案是错的,那么接下来就为大家揭晓答案。

  首先,我们要明确一点:

在 C 语言中,数组有自己特定的类型。

  那么,数组的类型又是什么呢?

数组的类型由数组中的元素类型和数组大小决定。

  因此,上面所定义的数组 a 的类型是 int[5],而不是 int

2. 定义数组类型

  明白数组的类型之后,我们就可以通过定义数组类型,来换一种方式来创建数组。

  在 C 语言中,可以通过 typedef 关键字为数组类型重命名:

typefet type(name)[size];
  • int 为数组中元素的数据类型
  • name 为将要创建的数组类型的名字
  • size 为将要创建的数组的元素个数

示例:

  • 定义数组类型
// 定义数组中元素类型为 int、数组元素个数为 5 的数据类型为 AINT5

// 定义数组中元素类型为 float、数组元素个数为 10 的数据类型为 AFLOAT10
typedef float(AFLOAT10)[10];
  • 声明数组
// 声明一个数据类型为 AINT5、数组名为 iArray 的数组
AINT5 iArray;
// 声明一个数据类型为 AFLOAT10、数组名为 fArray 的数组
AFLOAT10 fArray;

  现在大家应该明白了数组类型怎么去创建了吧。但是又出现个问题,比如 int 类型占 4 个字节、char 类型占 1 个字节,那么数组类型的大小是多少呢?

  下面通过一个例子来说明一下:

typedef int(AINT5)[5];
  • AINT5 数组类型说包含的数组元素为 int 类型,共包含 5 个元素
  • 由于每个 int 类型占用4个字节的内存空间
  • 因此,AINT5 所占用的内存空间为 20 个字节

  同理,通过上面可以推导出一个计算公式:

sizeof(TypeArray) = sizeof(type)·size
  • TypeArray 为数组类型
  • type 为数组类型中元素的类型
  • size 为数组类型所包含的数组元素个数

  那么,对于任意种类的数组类型所占内存空间的大小都可以通过这个公式进行计算,同时通过某个数组类型创建的数组所占空间的大小即为数组类型所占空间的大小

  到此为止,我们对数据类型应该了如指掌了吧。下面开始真正的话题 数组指针

3. 数组指针

  前面我们讲了一大堆关于数组类型的本质、数组类型的创建。那么你们可能会想数组类型也没有多大神奇,无非不就是换一种方式声明声明数组吗?我想说的是,有了数组类型,我们便可以定义数组指针了,你们想一想是不是呢。

  首先,我们先来回想一下指针声明的语法结构:

(type)* name = NULL;
  • type 为声明的这个指针的类型
  • name 为这个指针的名字

  通过指针声明的语法结构,我们可以定义 intfloatchar 等类型的指针。那么,现在有了数组类型,不就轻而易举的创建数组指针了吗。

(1)可以数组类型定义数组指针:

ArrayType* pointer;
  • ArrayType 为数组类型
  • pointer 为数组指针的名字

(2)可以通过数据类型直接定义:

type(*pointer)[n];
  • pointer 为数组指针变量名
  • type 为指向的数组的类型
  • n 为数组的元素个数

  截止到现在,我们明白了数组指针怎么创建,下面我们通过一个 demo 加深一下印象。

#include <stdio.h>

// 对数组元素为 int、数组元素个数为 5 的数组重命名为 AINT5
typedef int(AINT5)[5];
// 对数组元素为 flaot、数组元素个数为 10 的数组重命名为 AFLOAT10
typedef float[AFLOAT10][10];
// 对数组元素为 char、数组元素个数为 9 的数组重命名为 ACHAR9
typedef char[ACHAR9][9];

int main()
{
	// 声明一个数组类型为 AINT5、数组名字为 iArray 的数组
	AINT5 iArray;
	// 声明一个数组元素类型为 float、数组元素个数为 10、数组名字为 fArray 的数组
	float fArray[10];
	// 声明一个类型为 AFLOAT10、名字为 pfArray,并且值为数组 fArray 的地址的数组指针
	AFLOAT10* pfArray = &fArray;
	// 声明一个数组类型为 ACHAR9、数组名字为 cArray 的数组
	ACHAR9 cArray;
	
	// 声明一个类型为 char、元素个数为 9、名为 pc 并且值为 cArray 的数组指针
	char(*pc)[9] = &cArray;

	/*
	   首先 cArray 是数组 cArray 首元素的地址,其类型为 char*
	   char(*pcw)[4] 为一个数组指针,其要指向某个数组存储空间
	   因此 char(*pcw)[4] = cArray; 报错
	*/
	// char(*pcw)[4] = cArray;
	
	int i = 0;
	// 输出数组类型 AINT5 所占内存空间、数组 iArray 的大小
	printf("%d, %d\n", sizeof(AINT5), sizeof(iArray));

	for(i=0; i<10; i++)
	{
		// pfArray 为一个指针,其保存的值为数组 fArray 的地址,那么 *pfArray 所指向的内容便是 fArray,即 *pfArray = fArray
		// (*pfArray)[i] = i == fArray[i] = i
		(*pfArray)[i] = i;
	}

	for(i=0; i<10; i++)
	{
		// 将数组 fArray 中的数组元素遍历输出
		printf("%f\n", fArray[i]);
	}

	/* 
	   由于 pc 是一个指针,由指针运算得:
	   pc+1 = (unsigned int)pc + a·sizeof(*pc)
	   其中 sizeof(*pc) 为 pc 所指向的目标,即数组 cArray
	   (unsigned int)pc 为 pc 所保存的值,即数组 cArray 的地址值
	   pc+1 = &cArray + 9
	*/

	/* 
	   由于 pcw 是一个指针,由指针运算得:
	   pcw+1 = (unsigned int)pcw + a·sizeof(*pcw)
	   其中 sizeof(*pcw) 为 pcw 所指向的目标为:有 4 个 char 类型的元素构成,因此 sizeof(*pcw) = 4
	   (unsigned int)pcw 为 pcw 所保存的值,即数组 cArray 首元素地址值
	   pcw+1 = &cArray + 9
	*/
	printf("%p, %p, %p\n", &cArray, pc+1, pcw+1);
	
	return 0;
}

  上面这个 demo 中所有的代码的含义都通过注释的方式在文中标注出。同时,通过这个 demo 我们可以很清晰的对数组类型所占空间的大小及数组类型的创建、数组指针的创建及使用了如指掌。

  通过上面这个 demo 能够得出如下结论:

  • 指针运算适用于任何类型的指针
  • 数组指针与普通指针类似,无非指向的内容的是 数组 而已
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值