前言
本文旨在记录我在学习c语言过程中遇到的问题,分析并提高学习的效果,如果有不对的地方,欢迎指证。
文中部分内容参考GPT,在此感谢ppword提供的GPT工具支持,有了它就再也不用去找大神帮忙了。
一、什么是 C 语言数组
数组是一组相同类型的元素的集合,这些元素按照一定的顺序排列,可以通过索引访问每个元素。在 C 语言中,数组是一种非常重要的数据结构,它可以用来存储多个相同类型的数据,并且可以方便地对这些数据进行操作。
二、一维数组的创建与初始化
1. 数组的创建格式
type array_name[size];
其中,type
是数组元素的类型,array_name
是数组的名称,size
是数组的大小。
例如:
int num[10];
这是一个包含 10 个整数的数组。
2. 数组的初始化
可以在创建数组时对数组进行初始化,也可以在之后使用赋值操作进行初始化。
(1)创建时初始化:
type array_name[size] = {value1, value2, ..., valueN};
int num[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
(2)部分初始化:
int num[10] = {1, 2, 3};
可以只提供一部分初始值,其他元素将被自动初始化为 0。
(3)使用花括号指定初始值:
int num[10] = {};
如果花括号中不提供任何初始值,那么数组的所有元素都将被初始化为 0。
(4)使用初始化列表:
int num[] = {10, 20, 30, 40, 50};
这种方式适用于数组长度不确定的情况,可以根据初始化列表的数量来确定数组的长度。
这些是一些常见的数组初始化方式,你可以根据具体需求选择适合的初始化方式。无论哪种方式,都可以在创建数组时为数组的元素提供初始值。
3. 一维数组的使用
可以通过索引访问数组中的元素,索引从 0 开始,最大为数组大小减 1。
array_name[index];
例如:
int num[10];
num[5] = 100;
4. 一维数组在内存中的存储
数组在内存中是连续存储的,每个元素占用的内存大小与数组元素的类型相同。
例如:
int num[10];
这个数组在内存中的存储方式如下图所示:
| num[0] | num[1] | num[2] | num[3] | num[4] | num[5] | num[6] | num[7] | num[8] | num[9] |
三、二维数组的创建与初始化
1. 二维数组的创建格式
type array_name[size1][size2];
其中,type
是数组元素的类型,array_name
是数组的名称,size1
是第一维的大小,size2
是第二维的大小。
例如:
int num[3][4];
这是一个包含 3 行 4 列的整数二维数组。
2. 二维数组初始化
可以在创建数组时对数组进行初始化,也可以在之后使用赋值操作进行初始化。
(1)创建时初始化
type array_name[size1][size2] = {
{value11, value12, ..., value1N},
{value21, value22, ..., value2N},
...
{valueM1, valueM2, ..., valueMN}
};
例如:
int arry1[2][3] = {1,2,3,4,5,6};
int arry2[3][4] = {1,2,3,4,5,6};
int arry3[3][2] = { {1,2},{3,4},{5,6} };
(2)之后赋值初始化
type array_name[size1][size2];
for (int i = 0; i < size1; i++) {
for (int j = 0; j < size2; j++) {
array_name[i][j] = value;
}
}
例如:
int num[3][4];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
num[i][j] = i * 4 + j + 1;
}
}
3. 二维数组的使用
可以通过索引访问数组中的元素,索引的格式为array_name[row][col]
,其中row
表示行索引,col
表示列索引。
array_name[row][col];
例如:
int num[3][4];
num[1][2] = 100;
4. 二维数组在内存中的存储
二维数组在内存中是按行优先的方式存储的,即先存储第一行的元素,然后是第二行的元素,以此类推。
例如:
int num[3][4];
这个二维数组在内存中的存储方式如下图所示:
| num[0][0] | num[0][1] | num[0][2] | num[0][3] |
| num[1][0] | num[1][1] | num[1][2] | num[1][3] |
| num[2][0] | num[2][1] | num[2][2] | num[2][3] |
需要注意的是,二维数组在内存中的地址也是连续的。从侧面说明了二维数组也是一个一维数组,只不过定义的时候把它定义成了二维数组。
四、越界数组
当访问数组的索引超出数组的范围时,就会发生越界访问。例如,使用索引size
访问大小为size - 1
的数组。
int num[10];
num[10] = 100;
这种情况下,程序可能会出现错误,或者返回未定义的值。因此,在编写程序时,应该注意数组的大小和索引范围,避免发生越界访问。
五、数组指针、数组名、数组首元素
在 C 语言中,数组、指针和地址是非常重要的概念,它们之间有着密切的关系。下面通过一个例子来详细说明数组指针、数组名、数组第一个元素的地址之间的相同点和不同点。
#include <stdio.h>
int main() {
int array[5] = {10, 20, 30, 40, 50};
int *pointer = &array[0];
int *pointer2 = array;
printf("数组名: %p\n", array);
printf("数组第一个元素的地址: %p\n", &array[0]);
printf("数组指针: %p\n", pointer);
printf("数组指针 2: %p\n", pointer2);
return 0;
}
在这个例子中,我们定义了一个整数数组array
,并初始化了它的元素。然后,我们声明了一个整数指针pointer
,并将其指向数组的第一个元素。
我们使用%p
格式说明符来打印变量的地址。输出结果如下:
数组名: 0x7ff7b9cfd870
数组第一个元素的地址: 0x7ff7b9cfd870
数组指针: 0x7ff7b9cfd870
数组指针 2: 0x7ff7b9cfd870
可以看到,数组名array
、数组第一个元素的地址&array[0]
和数组指针pointer
、pointer2
的值都是相同的,都指向数组的第一个元素。
它们的相同点是:
- 它们都表示数组的首地址,即数组中第一个元素的地址。
- 它们在语法上可以相互转换,例如可以使用
&array[0]
或array
来获取数组的首地址,也可以使用pointer
来访问数组的元素。
它们的不同点是:
- 数组名是一个常量,它的值不能被修改,而指针是一个变量,可以指向不同的内存地址。
- 数组名可以作为左值使用,例如可以使用
array = 10
来修改数组的第一个元素的值,而指针不能作为左值使用,例如pointer = 10
是错误的。 - 数组名在表达式中会自动转换为指向数组第一个元素的指针,而指针在表达式中需要使用
*
运算符来解引用才能访问数组的元素。
希望这个例子能够帮助你更好地理解这些概念。如果你还有其他问题,请随时提问。