目录
3. 变长数组(VLA,Variable Length Array)
1 数组创建
数组是一个用于存储多个相同类型元素的数据结构。创建数组的方式有几种:
1.1 定义定长数组
int arr[5]; // 创建一个长度为5的整数数组
1.2 定义并初始化数组
int arr[5] = {1, 2, 3, 4, 5}; // 创建并初始化数组
1.3 定义部分初始化的数组
如果数组的元素数量小于定义时的大小,未初始化的元素会默认赋值为0。
int arr[5] = {1, 2}; // 数组内容为 {1, 2, 0, 0, 0}
在 C 语言中,声明数组时如果数组的大小可以从初始化列表中推导出来,那么是可以不显式指定数组大小的。具体来说,数组的大小可以由编译器自动推断。
int arr[] = {1, 2, 3, 4, 5};
2. 动态数组(动态分配)
动态数组的大小在程序运行时才确定,通常通过malloc
或calloc
等函数动态分配内存。
2.1 使用malloc
动态创建数组
int* arr = (int*)malloc(5 * sizeof(int)); // 创建一个包含5个整数的动态数组
这里,malloc
函数动态分配了一块内存,用于存储5个整数。
2.2 使用calloc
动态创建数组
int* arr = (int*)calloc(5, sizeof(int)); // 创建并初始化为0的动态数组
与malloc
不同,calloc
除了分配内存,还会将数组元素初始化为0。
2.3 动态数组初始化
for (int i = 0; i < 5; i++) { arr[i] = i + 1; // 初始化为 {1, 2, 3, 4, 5} }
2.4 释放动态数组内存
free(arr); // 释放动态数组内存
3. 变长数组(VLA,Variable Length Array)
变长数组是C99标准引入的特性,允许在运行时动态确定数组的大小(但局限于局部作用域中)。变长数组不像动态数组那样需要malloc
。
void function() {
int n = 5;
int arr[n]; // 创建一个大小为n的数组
for (int i = 0; i < n; i++) {
arr[i] = i + 1; // 初始化数组
}
}
这里,数组arr
的大小是运行时由变量n
决定的。
4.字符串和字符数组
字符串实际上是一个以 '\0'
结尾的字符数组,其中的每个元素都是一个字符。空字符(null character) '\0'
用来标记字符串的结束。字符串的末尾自动添加了这个空字符,所以字符串的实际长度是字符数加1(因为最后一个字符是空字符)。
4.1. 显式声明并初始化字符数组
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
4.2. 隐式声明并初始化字符数组:(声明字符串)
char greeting[] = "Hello";
重要说明:
char greeting[6]
:这里显式地指定了数组的大小为6,正好是 "Hello"
字符串的5个字符再加上一个 '\0'
。
char greeting[]
:在这种声明方式下,编译器会根据字符串的长度自动推断数组的大小,因此 greeting
数组的大小会是6。
5.数组详解篇
5.1. 数组作为参数
在C语言中,数组不能直接作为参数传递到函数中,实际上传递的是数组的指针。这意味着在函数内部修改数组的内容会影响原数组
#include <stdio.h>
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
printArray(arr, 5); // 将数组传递给函数
return 0;
}
在这个例子中,printArray
函数接受一个整数数组arr
以及它的大小size
作为参数。注意,数组arr
在传递时实际上是通过指针传递的。arr
实际上是一个指向 arr[0]
的指针。
5.2. 从函数返回数组
C语言不允许直接返回一个数组(数组本身不能作为返回类型)。但可以通过返回指向数组的指针来实现返回数组的效果。通常,可以通过静态数组或者动态分配内存来实现。
#include <stdio.h>
#include <stdlib.h>
int* createArray(int size) {
int* arr = (int*)malloc(size * sizeof(int)); // 动态分配内存
for (int i = 0; i < size; i++) {
arr[i] = i * i; // 初始化数组
}
return arr; // 返回指向数组的指针
}
int main() {
int size = 5;
int* arr = createArray(size); // 接收返回的指针
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
free(arr); // 记得释放内存
return 0;
}
这里的 arr
不是一个普通的静态数组,而是一个指针,它通过 malloc
函数动态地分配了一块内存,大小为 size * sizeof(int)
,这意味着可以存放 size
个 int
类型的元素。这个内存块实际上就是“数组”,但它并不是在栈上定义的,而是在堆上分配的。
5.3指向数组的指针
在C语言中,数组的名称可以看作是指向数组第一个元素的指针。通过这种方式,可以使用指针来访问数组中的元素。
#include <stdio.h>
int main() {
int arr[3] = {1, 2, 3};
int* p = arr; // 指针p指向数组arr的第一个元素
printf("%d\n", *p); // 输出数组的第一个元素,结果是1
printf("%d\n", *(p + 1)); // 输出数组的第二个元素,结果是2
return 0;
}
6.数组长度计算
对于 静态数组(如 int arr[] = {1, 2, 3};
),您可以使用 sizeof(arr) / sizeof(arr[0])
来计算数组的长度。
对于 字符串(字符数组),可以使用 strlen()
来计算字符串的长度,这个长度不包括结束的空字符 \0
。
strlen(str)
返回的是字符串str
的 字符数(不包括结束的\0
),而不是占用的字节数。strlen()
会遍历字符串直到遇到\0
,然后返回遇到的字符数量。