本文适用于大学的期中期末考试、专升本(专接本、专插本)考试、408等考研预科。如有相关题目疑问或建议欢迎在评论区进行互动。
转载请标明出处。
在深入学习C语言的数组之前,我们先回顾一下C语言的三大基本结构:顺序结构、选择结构和循环结构。这些结构构成了编程逻辑的基础,让我们能够编写出功能丰富、逻辑清晰的程序。
顺序结构保证了程序按照代码的书写顺序执行;选择结构(如 if
语句和 switch
语句)让我们能够根据不同的条件执行不同的代码分支;循环结构(如 for
、while
和 do...while
循环)允许我们重复执行一段代码,直到满足特定的退出条件。
现在,当我们对这些基本结构有了深刻的理解之后,我们可以迈向C语言中另一个强大的特性——数组。
数组是存储固定大小的同类型元素的集合,它使得数据的批量处理和管理变得简单高效。
数组作为C语言中一个核心的数据结构,它不仅能够存储一系列的数据,还允许我们通过索引快速访问和修改这些数据。无论是对数据进行排序、搜索还是变换,数组都提供了一种高效且直接的手段。
一维数组
在开头我们提到,数组是存储固定大小的同类型元素的集合。其中一维数组是数组的基本形式,具有连续的内存空间。
它们通常使用以下语法定义:
type arrayName[length];
/* type 是数据类型,如 int, float, char 等。
arrayName 是数组的名称。
length 是数组可以存储的元素数量。 */
其中的 length 我们也将其称之为数组下标,在C语言中,我们规定:
数组的下标从0开始
值得注意的是:
数组名 arrayName 不是变量,是数组元素存储的首地址,故为常量
arrayName[length] 是变量
由于 arrayName 是常量,故在定义初始化后只能一个一个赋值
(在字符数组中有另外两种定义后整体赋值的方法,在后面内容中会有所介绍)
举个例子:
a = {1, 2, 3, 4, 5}; //错误!不能整体赋值,只能逐一赋值 a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4; a[4] = 5; //正确!
数组的初始化是指在定义数组的同时对数组元素进行赋值,通常有以下两种类型:
- 静态初始化:
type arrayName[length] = {value1, value2, ...};
静态初始化不仅能对所有元素进行依次赋值,也可以只对部分元素赋值,但对于没有赋值的元素默认赋值为0(部分元素赋值后未赋值的才为0,若未进行赋值操作未赋值的为随机数)。
- 动态初始化:
type arrayName[length]; for (int i = 0; i < length; i++) { arrayName[i] = someValue; }
利用循环、函数、指针等方式进行赋值。
在C语言中,允许初始化数组时省略长度,其默认长度及为数组元素总和。
如果我们需要访问数组的元素,通常需要使用索引,索引从0开始:
element = arrayName[index];
/* element 是数组中的一个元素。
index 是元素的索引。 */
其边界为:
- 上界:
arrayName[length - 1]
- 下界:
arrayName[0]
而遍历数组的所有元素可以使用循环结构:
for (int i = 0; i < length; i++)
{
//使用 arrayName[i] 访问或修改元素
}
其内存分配常常遵循以下规则:
- 数组在栈上分配内存,创建时分配固定大小。
- 数组的内存地址是连续的。
对于数组的特点,我们可以简略的总结如下:
- 优点:访问速度快,内存连续,易于遍历。
- 缺点:大小固定,一旦声明不能改变。
这里举一个一维数组的经典例子:
#include <stdio.h> // 函数声明 void printArray(int arr[], int size); int main() { int numbers[5]; // 声明一个整型数组,可以存储5个元素 int i; // 手动初始化数组 numbers[0] = 10; numbers[1] = 20; numbers[2] = 30; numbers[3] = 40; numbers[4] = 50; // 打印数组元素 printf("手动初始化的数组元素:\n"); for (i = 0; i < 5; i++) { printf("%d ", numbers[i]); } printf("\n"); // 使用函数打印数组 printArray(numbers, 5); return 0; } // 函数定义 void printArray(int arr[], int size) { int i; printf("数组内容: "); for (i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); }
代码解析:
数组声明:在
main
函数中,声明了一个名为numbers
的整型数组,它可以存储5个整数。手动初始化:通过直接指定索引值的方式,对数组的每个元素进行初始化。
遍历数组:使用一个
for
循环遍历numbers
数组,并使用printf
函数打印每个元素的值。函数
printArray
:定义了一个接受整型数组和数组大小为参数的函数,用于打印数组的所有元素。函数内部同样使用for
循环遍历数组。函数调用:在
main
函数中调用printArray
函数,并传入numbers
数组及其大小,演示了如何将数组作为参数传递给函数。
二维数组
二维数组在C语言中可以看作是数组的数组,通常用于存储矩阵或表格数据。它可以用直角坐标系中的行和列来理解。
其定义语法如下:
type arrayName[rowSize][columnSize];
其中:
type
是数据类型(如int
,float
,char
等)。arrayName
是数组的名称。rowSize
是数组的行数。columnSize
是数组的列数。
类似的,arrayName
在题目中也简略的写为 arr
或 a
。
数组名不是变量,同样也是地址常量。
它的初始化同样分为两种,即静态初始话与动态初始化:
- 静态初始化:
type arrayName[rowSize][columnSize] = { {v11, v12, ..., v1n}, {v21, v22, ..., v2n}, ... {vm1, vm2, ..., vmn} };
- 动态初始化:
type arrayName[rowSize][columnSize]; for (int i = 0; i < rowSize; i++) { for (int j = 0; j < columnSize; j++) { arrayName[i][j] = someValue; } }
需要补充记忆的是以下两点:
C语言按行优先。
在初始化中,允许省略第一维(行)的长度,但不允许省略第二维(列)的长度。
通过这几个例子可以清晰的理解体会:
int a[2][3] = {{1,2,3},{4,5,6}}; //第一行的元素为 1,2,3, 第二行的元素为 4,5,6
int a[2][3] = {1,2,3,4,5,6}; //按行优先,第一行的元素为 1,2,3,第二行的元素为4,5,6
int a[2][3] = {{1},{2,3}}; //第一行的元素为1,0,0, 第二行的元素为2,3,0
int a[2][3] = {1,2,3}; //第一行的元素为1,2,3, 第二行的元素为 0,0,0
int a[][3] ={1,2,3,4,5,6}; //这里有6个元素,每行3列,故默认第一维的长度为2; //第一行的元素为1,2, 第二行的元素为 3,4,第三行的元素为 5,6
对于访问二维数组元素,同样使用以下方法:
element = arrayName[row][column];
其中:
element
是数组中的一个元素。row
是元素的行索引。column
是元素的列索引。
二维数组的边界即确保索引在有效的范围内:0 <= i < rowSize
且 0 <= j < columnSize
。
对于二维数组的遍历,使用嵌套循环即可遍历其所有元素:
for (int i = 0; i < rowSize; i++)
{
for (int j = 0; j < columnSize; j++)
{
//使用 arrayName[i][j] 访问或修改元素
}
}
其内存分配如下:
- 二维数组通常在栈上分配内存,内存是连续的。
- 行连续,但每行的列可能不连续,取决于每个元素的类型。
举一个经典的二维数组例子:
#include <stdio.h> int main() { int rows = 3; // 定义数组的行数 int columns = 4; // 定义数组的列数 int myArray[rows][columns]; // 声明一个3x4的二维数组 // 初始化二维数组 for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { myArray[i][j] = i * columns + j + 1; // 赋值示例:(i, j)位置的元素值为(i*4 + j + 1) } } // 打印二维数组 printf("二维数组内容:\n"); for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { printf("%d ", myArray[i][j]); } printf("\n"); } // 修改特定元素 myArray[1][2] = 999; // 将第二行第三列的元素修改为999 // 再次打印二维数组,展示修改结果 printf("修改后的二维数组内容:\n"); for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { printf("%d ", myArray[i][j]); } printf("\n"); } return 0; }
代码解析:
数组声明:声明了一个名为
myArray
的整型二维数组,具有3行4列。初始化二维数组:使用嵌套的
for
循环对数组进行初始化。循环中的i
代表行索引,j
代表列索引。打印二维数组:首先打印初始化后的二维数组内容,使用嵌套的
for
循环遍历数组并打印每个元素。修改元素:通过指定索引的方式,修改了数组中第二行第三列的元素值为999。
再次打印数组:修改元素后,再次打印整个数组,展示修改的结果。
字符数组
在学习字符数组之前,我们先需要了解一个概念:
C语言没有字符串类型,字符串是存放在字符数组中的。
所以,字符数组在C语言中是用来存储字符数据的数组。它通常用于处理字符串,即字符的集合。
它的定义语法如下:
char arrayName[length];
其中:
char
表示数组存储的是字符数据。arrayName
是数组的名称。length
是数组可以存储的字符数量。
其初始化类似于一维、二维数组,分为以下两种:
- 静态初始化(字符串字面量):
char arrayName[] = "Hello, World!";
- 动态初始化:
char arrayName[20]; for (int i = 0; i < 12; i++) { arrayName[i] = 'H' + (i % 2); // 例如初始化为 "HhHhHhHhHh" }
它使用索引访问或修改数组元素:
char element = arrayName[index];
arrayName[index] = 'a'; // 修改特定索引的字符
其中:
element
是数组中的一个字符。index
是字符的索引。
对于其中常用字符串操作函数,我们留到下一个章节单独进行详细介绍,这里仅列出部分简介。
C语言标准库 <cstring>
提供了多个用于操作字符数组的函数,如:
strcpy()
:复制字符串。strcat()
:连接字符串。strlen()
:计算字符串长度,不包括结束的空字符。strcmp()
:比较两个字符串。strchr()
:查找字符串中首次出现某个字符的位置。getchar()
:字符输入函数。putchar()
:字符输出函数。gets()
:字符串输入函数。puts()
:字符串输出函数。
在C语言中,字符数组经常用来表示字符串,但它们不是同一个概念:
- 字符数组是一个存储字符的固定大小的数组。
- 字符串是一个以空字符(
'\0'
)结尾的字符数组。
C语言字符串以空字符('\0'
)结尾,用于表示字符串结束。
举个例子:
char string[] = "Hello";
string[5] = '\0'; // 手动添加字符串结束标志
举一个经典的字符数组的例子:
#include <stdio.h> #include <string.h> // 函数声明 void printReversed(const char str[]); int main() { char myString[50]; // 声明一个字符数组,用于存储字符串 // 请求用户输入一个字符串 printf("请输入一个字符串:"); fgets(myString, sizeof(myString), stdin); // 使用fgets来读取一行文本 // 去除可能读取到的换行符 size_t len = strlen(myString); if(len > 0 && myString[len - 1] == '\n') { myString[len - 1] = '\0'; } // 打印原始字符串 printf("原始字符串: %s\n", myString); // 调用函数,打印反转后的字符串 printf("反转后的字符串: "); printReversed(myString); printf("\n"); return 0; } // 函数定义:打印字符串的反转 void printReversed(const char str[]) { int len = strlen(str); for (int i = len - 1; i >= 0; i--) { putchar(str[i]); } }
代码解析:
字符数组声明:在
main
函数中,声明了一个名为myString
的字符数组,预定义了大小为50。用户输入:使用
fgets
函数读取用户输入的一行文本,包括空格,存储在myString
中。去除换行符:
fgets
会将换行符也读取到字符串中,通过检查字符串的最后一个字符并将其替换为字符串结束符\0
来去除它。打印原始字符串:使用
printf
函数打印用户输入的原始字符串。字符串反转:定义了一个
printReversed
函数,它接收一个字符数组作为参数,并使用一个for
循环从后向前打印每个字符,实现字符串的反转。调用函数:在
main
函数中调用printReversed
函数,并传入myString
,打印反转后的字符串。
《衡庐浅析·C语言程序设计·第四章·数组》部分到这里就结束了,我会在后续章节编写一些题目或分享一些典型的例子以巩固所学的知识点。下一个知识点章节我们将会学习C语言中函数的相关知识,敬请期待,也欢迎大家在评论区进行互动!
标签:初始化,arrayName,int,元素,C语言,衡庐,数组,字符串,浅析 From: https://blog.csdn.net/m0_68962556/article/details/140746505