C语言数组

一维数组

  注意:“初始化数组”和“给数组赋值”是不同的概念,初始化是在声明数组的同时为其分配内存并赋予初值,给数组赋值是在数组已经声明和分配内存的情况下为数组元素赋予新的值

  声明一个长度为10的数组,系统会给每个元素分配未初始化值(未初始化的值是不确定的),并为其分配连续的内存地址

1
2
// 声明数组
int arr[10];

  声明一个长度为10的数组,并对数组中的部分元素赋予初始值(简称初始化),未初始化的部分系统将会为其赋值为0

1
2
3
4
5
// 声明数组,对部分元素初始化
int arr2[10] = { 1,2 };

// 将会输出 120
printf("arr2 = %d%d%d\n", arr2[0],arr2[1],arr2[2]);

  声明一个长度为10的数组,并对全部元素初始化

1
2
// 声明数组,对全部元素初始化
int arr3[10] = { 1,2,3,4,5,6,7,8,9,0 };

  声明数组但不指定长度,数组的长度将由{}中初始值的个数决定

1
2
// 声明数组,不指定数组长度
int arr4[] = { 1,2,3,4 };

  声明数组,并给指定的部分元素初始化

1
2
3
4
// 只给第一个和第四个元素赋初始值
int arr[5] = {[0] = 1, [3] = 4};
// 将会输出 10040
printf("arr = %d%d%d%d%d\n", arr[0],arr[1],arr[2],arr[3],arr[4]);

  注意,使用大括号给数组赋初始值时,只能在数组声明时赋值,否则会报错,因为声明数组时如果不赋初始值,编译器会自动为数组每个元素赋未初始化值,并分配连续的内存地址,数组名指向的内存地址一旦被分配就不可更改,所以数组声明后无法再使用大括号给数组赋值

1
2
3
4
5
6
// 声明数组
int arr[3];
// 数组被声明却未初始化
// 系统给每个元素赋未初始化值并分配内存地址
// 所以无法再使用{}对其进行初始化
arr = {1,2,3};

  在C语言中,数组名是一个指向数组首元素的指针常量,并不代表数组的所有元素的集合。如下代码中arr1是指向数组首元素的指针常量,并不等同于{1,2,3,4,5},所以无法将arr1作为初始值赋值给数组arr2;且因为C语言中的数组变量无法直接被赋值,只能给数组中的元素赋值或初始化赋值,所以数组变量arr1也不能作为地址值赋值给数组变量arr2

1
2
3
4
5
// 声明数组arr1,并对其赋初始值,正确
int arr1[5] = {1,2,3,4,5};

// 给数组arr2赋值,错误
int arr2[2] = arr1;

  我说实话在这里边获取数组长度的方式是真他妈的操蛋,不能直接像java那样arr.length,只能通过计算占用储存空间大小的方式获取数组长度

1
2
3
4
5
6
7
// 定义一个长度为3的数组
int arr[3];

// 数组占用的储存空间大小/元素占用的储存空间大小
int arrLength = sizeof(arr) / sizeof(int);

printf("数组arr长度 = %d", arrLength);

二维数组

  创建二维数组但未对数组进行初始化,系统会给每个元素分配默认值

1
2
// 3行4列二维数组,未初始化
int arr[3][4];

  创建二维数组并对数组部分初始化,未初始化的部分系统将会为其赋值为0

1
2
3
4
5
6
7
8
// 3行4列二维数组,部分初始化
int arr2[3][4] = {
{1,2,3},
{1,2,3,4}
};

// 将会输出0,因为第1行第4列的元素未进行初始化
printf("arr = %d\n",arr2[0][3]);

  创建二维数组并对所有元素赋值,元素的个数不可以超过指定的个数

1
2
3
4
5
6
// 3行4列二位数组,全部初始化
int arr3[3][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};

  创建二维数组时可以不指定具体行数,行数将在二维数组创建时动态决定,但必须指定列数

1
2
3
4
5
// 不指定行数,只指定列数
int arr4[][4] = {
{1,2,3,4},
{5,6,7,8}
};

  创建二维数组,并逐个对数组进行初始化,如下面9个元素,只对二维数组中[0][0][2][0]进行了初始化

1
2
3
4
5
6
7
// 逐个对数组进行初始化
int arr5[3][4] = {
1,2,3,4,5,6,7,8,9
};

// 将会输出 9,0,因为[2][1]未进行初始化
printf("arr5 = %d,%d", arr5[2][0], arr5[2][1]);

  创建二维数组,给指定部分元素初始化

1
int arr[][4] = {[0][1] = 1, [1][2] = 3};

char数组

  char数组的最后一个元素如果为\0,该数组就构成了一个字符串,否则只能是字符数组,无法构成字符串

1
2
3
char str[] = { 't','e','s','t','\0' };
// 将会输出 test
printf("字符串 = %s", str);

  如果直接给char数组赋值字符串,那么它的最后一位必定是\0,在C语言中\0是空字符(null character),用于表示字符串的结束,如果使用printf输出%c格式的\0,将会输出一个空格,表示有不可见的字符被输出。

1
2
3
4
5
6
// 储存长度为4的字符串,则char类型数组的长度至少为5,因为最后一位需要储存\0
char str[] = "test"; // 等号右边这样写{"test"}也可以
// 将会输出 0,因为最后一个元素是 \0
printf("str = %d\n", str[4]);
// 将会输出空,因为 \0 代表空
printf("str = %c\n", str[4]);

  \0会被计入数组占用的字节,但不会被计入字符串长度之内,其中strlen()string.h下的函数,用于计算字符串长度

1
2
3
4
5
6
char str[] = "test";

// 字符串占用的字节数为 5 ,因为最后一位是 \0
printf("arr size = %d\n", sizeof str);
// 字符串长度为 4 ,\0不计入其中
printf("arr length = %d\n", strlen(str));