-
基本概念
- 数组是C语言中一种用于存储多个相同类型数据的数据结构。这些数据在内存中是连续存储的,可以通过索引(下标)来访问数组中的各个元素。数组的索引从0开始,这是C语言的规定。例如,一个有
n
个元素的数组,其索引范围是从0到n - 1
。
- 数组是C语言中一种用于存储多个相同类型数据的数据结构。这些数据在内存中是连续存储的,可以通过索引(下标)来访问数组中的各个元素。数组的索引从0开始,这是C语言的规定。例如,一个有
-
一维数组
- 定义和初始化
- 定义方式:
- 数据类型 数组名[数组大小];
- 例如:
int arr[5];
,这就定义了一个名为arr
的整型数组,它可以存储5个整数。
- 初始化方法:
- 可以在定义数组时进行初始化。例如:
int arr[5] = {1, 2, 3, 4, 5};
,将数组arr
的5个元素分别初始化为1、2、3、4、5。 - 如果初始化时提供的初始值个数少于数组大小,剩下的元素会被自动初始化为0(对于数值类型)或
\0
(对于字符数组)。例如:int arr[5] = {1, 2};
,则arr[2]
、arr[3]
和arr[4]
会被初始化为0。 - 也可以省略数组大小,让编译器根据初始值的个数来确定数组大小。例如:
int arr[] = {1, 2, 3};
,此时数组arr
的大小为3。
- 可以在定义数组时进行初始化。例如:
- 定义方式:
- 元素访问
- 通过索引访问数组元素,格式为数组名[索引]。例如,对于前面定义的
arr
数组,arr[0]
表示第一个元素,其值为1;arr[3]
表示第四个元素,其值为4。
- 通过索引访问数组元素,格式为数组名[索引]。例如,对于前面定义的
- 示例代码 - 计算一维数组元素的平均值
- 定义和初始化
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += arr[i];
}
double average = (double)sum / 5;
printf("数组元素的平均值为:%lf\n", average);
return 0;
}
- **解释**:
- 首先定义并初始化了一个包含5个整数的数组`arr`。然后通过一个`for`循环,从索引0到4遍历数组,将每个元素的值累加到变量`sum`中。最后计算平均值,将`sum`转换为双精度浮点数后除以元素个数5,并将结果存储在`average`变量中,通过`printf`函数输出平均值。
- 二维数组
- 定义和初始化
- 定义方式:
- 数据类型 数组名[行数][列数];
- 例如:
int matrix[3][4];
,定义了一个名为matrix
的二维整型数组,它有3行4列,总共可以存储3 * 4 = 12
个整数。
- 初始化方法:
- 按行初始化。例如:
int matrix[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
,这是最直观的初始化方式,将数组的每一行用花括号括起来,分别初始化每一行的元素。 - 也可以省略第一维(行数)的大小,让编译器根据初始化值的行数来确定。例如:
int matrix[][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
,此时编译器会根据提供的两行初始化值确定数组有2行。
- 按行初始化。例如:
- 定义方式:
- 元素访问
- 通过两个索引来访问元素,格式为数组名[行索引][列索引]。例如,对于前面定义的
matrix
数组,matrix[1][2]
表示第二行(索引从0开始,所以是1)第三列(索引从0开始,所以是2)的元素,其值为7。
- 通过两个索引来访问元素,格式为数组名[行索引][列索引]。例如,对于前面定义的
- 示例代码 - 打印二维数组
- 定义和初始化
#include <stdio.h>
int main() {
int matrix[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
- **解释**:
- 定义并初始化了一个`3x4`的二维数组`matrix`。然后使用嵌套的`for`循环来访问数组元素。外层`for`循环控制行数,从0到2;内层`for`循环控制列数,从0到3。在每次内层循环中,通过`printf`函数输出当前元素的值,并在每个元素后添加一个空格。每一行的元素输出完后,通过`printf("\n")`换行,最终打印出整个二维数组。
- 字符数组和字符串
- 字符数组的定义和初始化
- 定义方式与其他数组类似。例如:
char str[10];
,定义了一个可以存储10个字符的字符数组。 - 初始化可以直接赋值字符。例如:
char str[5] = {'H', 'e', 'l', 'l', 'o'};
,这就将字符数组str
的前5个元素分别初始化为H
、e
、l
、l
、o
。
- 定义方式与其他数组类似。例如:
- 字符串的概念和存储
- 在C语言中,字符串是以
\0
(空字符)结尾的字符序列。当把一个字符串赋值给字符数组时,编译器会自动在字符串末尾添加\0
。例如:char str[] = "Hello";
,这个字符数组实际上存储了Hello\0
,\0
用于标记字符串的结束。
- 在C语言中,字符串是以
- 字符串处理函数
strcpy()
函数:用于将一个字符串复制到另一个字符数组中。例如:char str1[10], str2[] = "World"; strcpy(str1, str2);
,这就将str2
中的字符串复制到了str1
中。strcat()
函数:用于将一个字符串连接到另一个字符数组中的字符串后面。例如:char str1[20] = "Hello"; char str2[] = " World"; strcat(str1, str2);
,结果str1
中的字符串变为Hello World
。strlen()
函数:用于计算字符串的长度(不包括\0
)。例如:char str[] = "Hello"; int len = strlen(str);
,则len
的值为5。
以下是关于C语言数组的详细介绍:
- 字符数组的定义和初始化
一维数组
- 创建与初始化:
- 创建格式为
type_t arr_name[const_n];
,其中type_t
是数组元素类型,const_n
是常量表达式,用于指定数组大小。例如int arr[5];
创建了一个包含5个int
类型元素的数组. - 初始化有多种方式,如下表所示:
|初始化方式|示例|说明|
- 创建格式为
|完全初始化|int arr[5] = {1, 2, 3, 4, 5};
|数组的每个元素都被明确赋值|
|不完全初始化|int arr[5] = {1, 2, 3};
|只初始化了前三个元素,剩余元素默认初始化为0|
|省略数组长度初始化|int arr[] = {1, 2, 3, 4};
|编译器根据初始化元素的个数确定数组长度为4|
- 内存布局:一维数组在内存中是连续存储的,每个元素之间的地址差是
sizeof(element_type)
个字节,其中element_type
是数组元素的数据类型。例如,对于int arr[5]
,假设arr[0]
的地址是0x1000
,那么arr[1]
的地址是0x1000 + sizeof(int)
,以此类推. - 数组名的含义:数组名在大多数情况下代表数组的首地址,是一个常量指针。但在
sizeof
操作符中,sizeof(arr)
计算的是整个数组的大小;在&arr
操作中,得到的是整个数组的地址. - 遍历方式:通常使用
for
循环遍历一维数组,如下所示:
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
return 0;
}
也可以使用指针的方式遍历,如下所示:
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;
for (int i = 0; i < 5; i++) {
printf("%d ", *p);
p++;
}
return 0;
}
- 作为函数参数:当一维数组作为函数参数传递时,实际上传递的是数组的首地址,函数中对数组的操作会影响到原始数组。例如:
#include <stdio.h>
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
printArray(arr, sizeof(arr) / sizeof(arr[0]));
return 0;
}
二维数组
- 创建与初始化 :
- 创建格式为
type_t arr_name[num_rows][num_cols];
,例如int arr[3][4];
创建了一个包含3行4列共12个int
类型元素的二维数组。 - 初始化方式如下表所示:
|初始化方式|示例|说明|
- 创建格式为
|按行初始化全部元素|int arr[2][3] = { {1, 2, 3}, {4, 5, 6} };
|明确地为每一行的元素赋值|
|部分初始化|int arr[3][4] = { {1, 2}, {5, 6, 7} };
|第一行前两个元素初始化为1和2,其余自动为0;第二行前三个元素初始化为5、6、7,第四个元素自动为0|
|完全由0组成的数组|int arr[3][4] = {0};
|所有元素都初始化为0|
|省略行初始化|int arr[][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
|编译器根据初始化列值的数量计算数组的行数|
- 内存布局:二维数组在内存中也是连续存储的,同一行的元素地址相差
sizeof(element_type)
个字节,不同行首元素之间的地址差为num_cols * sizeof(element_type)
,其中num_cols
是二维数组的列数,element_type
是数组元素的数据类型. - 使用方式:通过下标来访问二维数组元素,第一个下标表示行,第二个下标表示列,且下标均从0开始。例如:
#include <stdio.h>
int main() {
int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
printf("%d\n", arr[1][2]); // 输出第二行第三列的元素7
return 0;
}
同样可以使用嵌套的for
循环遍历二维数组,如下所示:
#include <stdio.h>
int main() {
int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
- 作为函数参数:二维数组作为函数参数时,函数形参的声明可以指定第二维的大小,第一维的大小可以省略,但在函数内部访问数组元素时,需要确保不越界。例如:
#include <stdio.h>
void print2DArray(int arr[][4], int num_rows) {
for (int i = 0; i < num_rows; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main() {
int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
print2DArray(arr, 3);
return 0;
}
字符数组
- 创建与初始化:字符数组的创建方式与其他类型的数组类似,例如
char str[10];
创建了一个包含10个字符元素的字符数组。初始化可以使用字符常量逐个初始化,也可以使用字符串常量初始化,如下表所示:
|初始化方式|示例|说明|
|逐个字符初始化|char str[5] = {'h', 'e', 'l', 'l', 'o'};
|明确地为每个字符元素赋值|
|使用字符串常量初始化|char str[6] = "hello";
|使用字符串常量初始化字符数组,字符串末尾会自动添加’\0’作为结束标志|
- 特殊之处:由于字符串是以’\0’作为结束标志的字符序列,所以在处理字符数组时,需要注意字符串操作函数对’\0’的依赖。例如,
strlen
函数用于计算字符串的长度,不包括’\0’;而sizeof
函数计算的是字符数组的大小,包括’\0’. - 常用操作:常见的字符数组操作包括字符串复制、连接、比较等,C语言提供了相应的标准库函数来实现这些操作,如
strcpy
、strcat
、strcmp
等。例如:
#include <stdio.h>
#include <string.h>
int main() {
char str1[10] = "hello";
char str2[10];
strcpy(str2, str1);
printf("%s\n", str2);
char str3[20] = "world";
strcat(str1, str3);
printf("%s\n", str1);
int result = strcmp(str1, "helloworld");
if (result == 0) {
printf("两个字符串相等\n");
} else {
printf("两个字符串不相等\n");
}
return 0;
}