外观
C 语言入门(七)
前言
快到尾声了,再坚持坚持!🤗
七、数组
7.1 数组
数组是一组相同类型的值,按照顺序储存在一起。
c
// 数组的声明
int arr[100];
// 大括号赋值声明
int a[5] = {22, 37, 3490, 18, 95};
上面声明了一个arr
数组,里面包含100个成员,每个成员都是int
类型。
注意
- 声明数组时,必须给出数组的大小。
- 数组的成员从
0
开始编号,数组下标比长度小1。
成员赋值
c
arr[0] = 13;
// 大括号赋值
int a[5] = {22, 37, 3490, 18, 95};
// 省略成员数量,编译器会自动确定数组的长度
int a[] = {22, 37, 3490}
// 全部成员置零
int a[100] = {0};
注意
- 使用大括号赋值时,必须在数组声明时赋值。
- 使用大括号赋值后,再用大括号重新赋值不被允许。
- 使用大括号赋值时,大括号的值不能多于数组的长度。
- 如果大括号的值,少于数组的成员数量,那么未赋值的成员自动初始化为
0
。
数组长度
sizeof
运算符会返回整个数组的字节长度。
c
int arr[12];
printf("%zu\n", sizeof(arr)); // 48
printf("%zu\n", sizeof(int)); // 4
// 数组长度
printf("%zu\n", sizeof(arr) / sizeof(int)); // 12
数组整体的字节长度除以某个数组成员的字节长度,就可以得到数组的成员数量(即数组长度)。
7.2 多维数组
用到二维就行了,除非你有经过《线性代数》洗礼过的大脑😇
C 语言允许声明多个维度的数组,有多少个维度,就用多少个方括号。
c
// 二维数组
int arr[5][5];
// 三维数组
int arr[5][5][5];
成员赋值
多维数组也可以使用大括号,一次性对所有成员赋值。
c
// 指定赋值
int arr[1][3] =5;
// 大括号赋值
int arr[2][3] = {
{0, 1, 2},
{3, 4, 5}
};
7.3 数组的地址
指针和数组
首先就是指针和数组了,指针和数组分为指针数组和数组指针,在C语言中,因为数组本身就是一个常量指针,所以通常可以转化为指针使用。
指针数组
指针数组本质就是一个数组,其中的每个元素都是指向某种数据类型的指针。
TIP
指针数组通常在处理不定数量元素的数据结构时有很大作用,如动态分配的字符串数组或动态创建的结构体数组。
c
#include <stdio.h>
int main() {
int num1 = 10, num2 = 20, num3 = 30;
// 声明一个整数指针数组,包含三个指针
int *var[3]={&num1,&num2,&num3};
// 使用指针数组访问这些整数变量的值
printf("指针数组[0]的值: %d\n", *var[0]);
printf("指针数组[1]的值: %d\n", *var[1]);
printf("指针数组[2]的值: %d\n", *var[2]);
return 0;
}
/* >>
指针数组[0]的值: 10
指针数组[1]的值: 20
指针数组[2]的值: 30
*/
这样看来,指针数组和数组差不多嘛。只不过一个存变量值,一个存内存地址罢了😮
数组指针
照上面的说法,想必聪明的你已经知道了。数组指针本质就是指针,不过指向数组罢。
上面说过了,“在C语言中,因为数组本身就是一个常量指针,所以通常可以转化为指针使用。”,接下来让我们看看,怎么个事?🤔
c
#include <stdio.h>
int main () {
/* 带有 5 个元素的整型数组 */
int var[5] = {1,2,3,4,5};
int *p=var;
/* 输出数组中每个元素的值 */
printf( "使用数组的数组值\n");
for (int i = 0; i < 5; i++ ) {
printf("*(var + %d) : %d\n", i, *(var + i) );
}
printf( "使用数组指针的数组值\n");
for (int i = 0; i < 5; i++ ) {
printf("*(p + %d) : %d\n", i, *(p + i) );
}
return 0;
}
/* >>
使用数组的数组值
*(p + 0) : 1
*(p + 1) : 2
*(p + 2) : 3
*(p + 3) : 4
*(p + 4) : 5
使用数组指针的数组值
*(var + 0) : 1
*(var + 1) : 2
*(var + 2) : 3
*(var + 3) : 4
*(var + 4) : 5
*/
怎么样?懵了吧。哈哈哈🤣
上述我们说过数组本身就是个常量指针,它指向数组第一个元素的内存地址&var[0]
,且不可变。所以 *var=var[0]
。这样你就明白了,数组名可以当作指针使用。那么p
指针呢?p
指代了var
指针,所以其实你不用也无伤大雅。
7.4 字符串
在C 语言没有单独的字符串类型,字符串被当作字符数组,即char
类型的数组。
c
{'H', 'e', 'l', 'l', 'o', '\0'}
// 等价于
"Hello"
在字符串结尾,C 语言会自动添加\0
字符,表示字符串结束。这样C 语言在读取到字符是\0
时,就知道字符串结束了。
特殊表示
如果字符串内部包含双引号,可使用反斜杠转义。反斜杠还可以表示其他特殊字符,比如换行符(\n
)、制表符(\t
)等。
c
"She replied, \"It does.\""
"Hello, world!\n"
如果字符串过长,可以使用反斜杠(\
)结尾,将一行拆成多行。或者合并多个字符串字面量。
c
"hello \
world"
// 简化版(字符串之间没有间隔,或者只有空格,C 语言会将它们自动合并)
"Hello, ""how are you ""today!";
字符串的声明
字符串可以声明成一个字符数组,也可以声明成一个指针,指向字符数组。
c
// 写法一
char string[] = "Hello, world!";
// 写法二
char* string = "Hello, world!";
区别:
- 指针指向的字符串,被当作常量,不能修改字符串本身。数组声明字符串可以修改任意成员。
c
char* string = "Hello, world!";
string[0] = 'z'; // 错误
char string[] = "Hello, world!";
string[0] = 'z';
- 指针变量可以指向其它字符串。字符数组变量不能指向另一个字符串。
c
char* string = "hello";
string = "world";
char string[] = "hello";
string = "world"; // 报错
写在最后
数组是一个强有力的“结构工具”,用好它吧🤗