目录
- C语言中的数组:掌握数据的有序集合【一维数组,二维数组,字符串数组】
- 一维数组
- 一维数组的创建
- 数组的七种初始化
- 完全初始化:
- 部分初始化:
- 字符数组的初始化:
- 自动初始化为0:
- 使用`memset`函数初始化:
- 循环初始化:
- 指定初始化器(`c99`,`gcc`)支持:
- 一维数组的使用
- 案例1:统计随机数的分布
- 案例2:统计20个1-10的随机数的分布并打印直方图
- 案例3:给定一个数组,输出数组元素不重复的全排列。
- 一维数组在内存中的存储
- 二维数组
- 二维数组的声明
- 二维数组的创建
- 二维数组的初始化
- 二维数组的使用
- 二维数组在内存中存储
- 数组越界问题:
- 字符数组
- 字符数组的定义
- 字符数组初始化
- 字符数组的输入输出和常用函数
- 字符数组中单词计数问题以及多维数组的解释
- 数组作为函数参数
- 结论
C语言中的数组:掌握数据的有序集合【一维数组,二维数组,字符串数组】
在C语言中,数组是一种非常基础且重要的数据结构,它允许我们存储相同类型的数据元素的集合。通过使用数组,我们可以有效地管理和操作一组相关数据,而无需为每个数据元素创建单独的变量。本文将深入探讨C语言中数组的概念、声明、初始化和操作,帮助你更好地理解和运用这一关键特性。
一维数组
数组Array
也是一种复合数据类型,它由一系列相同的类型元素组成,数组的存储和结构体成员类似,数组的元素存储空间也是相邻的。
例如定义一个由4
个int
型元素组成的数组count:int count[4];
,数组类型的长度应该用一个整型常量表达式来指定。数组中通过下表或者索引index
来访问。
一维数组的创建
类型说明 数组名 [ 常量表达式 ];
例:
输出结果:
数组的七种初始化
完全初始化:
完全初始化:在声明数组的同时给出数组所有元素的值。
部分初始化:
只给数组的前面一部分元素赋值,剩余的元素会被自动初始化为0,对于基本数据类型。
字符数组的初始化:
字符数组可以通过字符串进行初始化,其余的为"0"
。
自动初始化为0:
对于静态数组和静态存储器的局部数组,如果没有明确初始化,他们会被自动初始化为0
。
使用memset
函数初始化:
memset
函数可以用来将数组的每一个字节设置为特定的值,通常用于将数组初始化为0
,或者其他重复值,注意memset函数定义包含在头文件string.h
中。
函数原型:
void *memset(void *s, int c,unsigned long n); // 将s指向的内存位置后面n个字节的存储空间替换为c;
输出结果:
循环初始化:
使用循环结构初始化,逐个设置数组元素的值。
指定初始化器(c99
,gcc
)支持:
c99
标准引入了指定初始化器,允许初始化数组的特定元素。
一维数组的使用
对于数组,使用”[]“
,下表引用操作符,即arr[0]
为数组首元素,arr[n-1]
为最后一个元素。
案例1:统计随机数的分布
输出结果:
案例2:统计20个1-10的随机数的分布并打印直方图
输出结果:
案例3:给定一个数组,输出数组元素不重复的全排列。
输出结果:
一维数组在内存中的存储
二维数组
二维数组的声明
二维数组的声明与一维数组相同,一般形式如:
类型说明符 数组名[
常量表达式1
][常量表达式2
];
注意:二维数组行下标的取值范围是[0~n-1]
列下标取值范围是[0~m-1]
,最大元素标识为 arr[n-1,m-1];
二维数组的创建
二维数组的初始化
//案例一
int a[3][4] = {{1},{2},{3}};等价:int a[3][4] = {{1,0,0,0},{2,0,0,0},{3,0,0,0}};
//案例二
int a[3][4] = {{1}};等价:int a[3][4] = {{1,0,0,0},{0,0,0,0},{0,0,0,0}};
当元素与少于数组总体元素的时候,剩余的元素自动初始化为0
;对于short
、int
、long
,就是整数0
;对于char
,就是字符 '\0'
;对于float
、double
,就是小数0.0
。
二维数组的使用
数组中每个元素都有一个序号,这个序号从0
开始,称为下表index
,例如a[0][2]
表示第1行第三个元素,a[3][5]
表示第四行第6
个元素。所以我们可以直接通过下表访问数组中元素的值。
通过遍历下标拿到对应元素值:
输出结果:
修改下标值:可以通过下标访问数组的值,也可以使用下标对数组的值进行修改。
输出结果:
二维数组在内存中存储
数组越界问题:
数组的下标是有范围限制的,数组下标规定是从0
开始的,如果数组有n
个元素,最后一个元素的下标就是n-1
,所有数组下标如果小于0
或者大于n-1
,就是数组越界访问了,超出了数组合法空间的访问。c
语言本身是不做数组下标越界检查,编辑器也不一定报错,但是编译器不报错并不意味着程序就正确的,在写代码时最好自己做一个数组越界的检查。
字符数组
字符数组的定义
用来存放字符数据的数组是字符数组,C
语言用字符数组存放字符串,字符数组中的各元素依次存放字符串的各字符,一维数组存放一个字符串,每个数组元素存放一个字符。二位数组存放多个一维数组也就是字符串,二维数组的行数是字符串的个数。
定义格式:char 数组名[常量表达式];
字符数组初始化
在C语言中,字符串数组是一个非常实用的概念,它允许存储和操作多个字符串。字符串在C语言中通常表示为字符数组,以空字符'\0'
结尾,因此,字符串数组可以被看作是字符数组的数组,其中每个元素都是一个独立的字符串。
注意:当你初始化字符串数组时,每个字符串的长度不需要相同,但是所有字符串的长度都必须小于或等于你在声明时指定的最大长度。
强调:字符串实际占有单元的数量等于字符串长度+1。定义时注意考虑元素总个数应比实际长度多1。
字符数组的输入输出和常用函数
字符数组中单词计数问题以及多维数组的解释
c语言中,处理字符串和字符数组经常涉及到单词计数的问题,一个典型的场景就是从一个句子或段落中统计单词的数量,这通常可以通过查找空格或其他分隔符来实现。下面写一个简单的示例,演示如何在一个字符串中技术单词。
输出结果:
在这段代码中,countWords
函数通过检查每一个字符是否为空格或制表符(由isspace
函数判断),来确定单词的边界。当遇到非空格字符且之前没有处于单词中时,单词计数器就会增加。
数组作为函数参数
C语言中,当你将数组作为函数参数的时候,实际上传递的是该数组的地址,也就是指向数组首元素的指针,这一特性使得函数在函数内部可以直接访问和修改数组的内容,但无法改变数组的大小。
当你在函数定义中使用数组类型作为参数时,例如void func(int arr[])
,这实际上被编译器处理为void func(int *arr)
。也就是说,数组名在这里退化为一个指针,这个指针指向数组的第一个元素。
例1:通过函数传递数组并打印
输出结果:
例2:修改数组内容:
输出结果:
注意:
- 数组大小:由于只传递了数组的首地址,函数内部无法知道数组的实际大小,除非你显式地传递它。
- 修改数组:尽管可以修改数组内容,但不能修改数组本身(如增加或减少元素)。
- 避免越界:在函数内部操作数组时,必须确保不会访问超出数组边界的位置。
总之,C语言中数组作为函数参数时,理解其实质上是传递指针这一点非常重要,这样可以帮助你更有效地编写和调试代码。
结论
数组是C语言中处理数据的有力工具,它们提供了一种简单有效的方式来存储和操作一系列相同类型的数据。理解如何声明、初始化和操作数组对于任何C程序员来说都是至关重要的。希望本文能帮助你更深入地了解和利用数组的潜力!