- C编程教程
- C语言 - 首页
- C语言基础
- C语言 - 概述
- C语言 - 特性
- C语言 - 历史
- C语言 - 环境搭建
- C语言 - 程序结构
- C语言 - Hello World
- C语言 - 编译过程
- C语言 - 注释
- C语言 - 词法单元
- C语言 - 关键字
- C语言 - 标识符
- C语言 - 用户输入
- C语言 - 基本语法
- C语言 - 数据类型
- C语言 - 变量
- C语言 - 整数提升
- C语言 - 类型转换
- C语言 - 类型强制转换
- C语言 - 布尔值
- C语言中的常量和字面量
- C语言 - 常量
- C语言 - 字面量
- C语言 - 转义序列
- C语言 - 格式说明符
- C语言中的运算符
- C语言 - 运算符
- C语言 - 算术运算符
- C语言 - 关系运算符
- C语言 - 逻辑运算符
- C语言 - 位运算符
- C语言 - 赋值运算符
- C语言 - 一元运算符
- C语言 - 自增和自减运算符
- C语言 - 三元运算符
- C语言 - sizeof 运算符
- C语言 - 运算符优先级
- C语言 - 其他运算符
- C语言中的决策语句
- C语言 - 决策语句
- C语言 - if 语句
- C语言 - if...else 语句
- C语言 - 嵌套 if 语句
- C语言 - switch 语句
- C语言 - 嵌套 switch 语句
- C语言中的循环
- C语言 - 循环
- C语言 - while 循环
- C语言 - for 循环
- C语言 - do...while 循环
- C语言 - 嵌套循环
- C语言 - 无限循环
- C语言 - break 语句
- C语言 - continue 语句
- C语言 - goto 语句
- C语言中的函数
- C语言 - 函数
- C语言 - 主函数
- C语言 - 按值调用函数
- C语言 - 按引用调用函数
- C语言 - 嵌套函数
- C语言 - 变参函数
- C语言 - 用户自定义函数
- C语言 - 回调函数
- C语言 - return 语句
- C语言 - 递归
- C语言中的作用域规则
- C语言 - 作用域规则
- C语言 - 静态变量
- C语言 - 全局变量
- C语言中的数组
- C语言 - 数组
- C语言 - 数组的特性
- C语言 - 多维数组
- C语言 - 将数组传递给函数
- C语言 - 从函数返回数组
- C语言 - 变长数组
- C语言中的指针
- C语言 - 指针
- C语言 - 指针和数组
- C语言 - 指针的应用
- C语言 - 指针运算
- C语言 - 指针数组
- C语言 - 指向指针的指针
- C语言 - 将指针传递给函数
- C语言 - 从函数返回指针
- C语言 - 函数指针
- C语言 - 指向数组的指针
- C语言 - 指向结构体的指针
- C语言 - 指针链
- C语言 - 指针与数组的区别
- C语言 - 字符指针和函数
- C语言 - NULL 指针
- C语言 - void 指针
- C语言 - 悬空指针
- C语言 - 解引用指针
- C语言 - 近指针、远指针和巨大指针
- C语言 - 指针数组的初始化
- C语言 - 指针与多维数组的区别
- C语言中的字符串
- C语言 - 字符串
- C语言 - 字符串数组
- C语言 - 特殊字符
- C语言中的结构体和联合体
- C语言 - 结构体
- C语言 - 结构体和函数
- C语言 - 结构体数组
- C语言 - 自引用结构体
- C语言 - 查找表
- C语言 - 点(.)运算符
- C语言 - 枚举(enum)
- C语言 - 结构体填充和打包
- C语言 - 嵌套结构体
- C语言 - 匿名结构体和联合体
- C语言 - 联合体
- C语言 - 位域
- C语言 - typedef
- C语言中的文件处理
- C语言 - 输入输出
- C语言 - 文件I/O (文件处理)
- C语言预处理器
- C语言 - 预处理器
- C语言 - 预处理指令
- C语言 - 预处理器运算符
- C语言 - 宏
- C语言 - 头文件
- C语言中的内存管理
- C语言 - 内存管理
- C语言 - 内存地址
- C语言 - 存储类
- 其他主题
- C语言 - 错误处理
- C语言 - 可变参数
- C语言 - 命令执行
- C语言 - 数学函数
- C语言 - static关键字
- C语言 - 随机数生成
- C语言 - 命令行参数
- C编程资源
- C语言 - 问答
- C语言 - 快速指南
- C语言 - 速查表
- C语言 - 有用资源
- C语言 - 讨论
C语言中的变长数组
C语言中的变长数组也称为变尺寸数组或运行时尺寸数组。它是一个长度在运行时确定而不是在编译程序时确定的数组。其大小取决于程序运行期间生成的、通常从用户那里接收到的输入值。
通常,数组大小在程序中预先声明如下:
int arr[10];
一旦声明,数组的大小在程序执行期间保持固定,并且不能在运行时更改。但是,对于变长数组(VLA),编译器会在堆栈上分配具有自动存储期的内存。对VLA的支持是在C99标准中添加的。
创建变长数组
创建变长数组的语法如下:
void arr_init(int length){ int arr[length]; //code using arr; };
示例
下面的例子演示了如何创建一个变长数组:
#include <stdio.h> int main(){ int i, j; int size; // variable to hold size of one-dimensional array printf("Enter the size of one-dimensional array: "); scanf("%d", &size); int arr[size]; for(i = 0; i < size; ++i){ printf("Enter a number: "); scanf("%d", &j); arr[i] = j; } for(i = 0; i < size; ++i) printf("a[%d]: %d\n", i, arr[i]); return 0; }
输出
运行这段代码时,它会要求你输入数组的大小。请注意,数组的长度在声明时不是固定的。你可以在运行时定义其大小。
Enter the size of one-dimensional array: 5 Enter a number: 1 Enter a number: 5 Enter a number: 7 Enter a number: 8 Enter a number: 7 a[0]: 1 a[1]: 5 a[2]: 7 a[3]: 8 a[4]: 7
二维变长数组
我们还可以声明和使用二维变长数组。
示例1
看下面的例子:
#include <stdio.h> int main(){ int i, j, x; int row, col; // number of rows & columns of two D array printf("Enter number of rows & columns of 2-D array:\n"); scanf("%d %d", &row, &col); int arr2D[row][col]; for(i = 0; i < row; ++i){ for(j = 0; j < col; ++j){ printf("Enter a number: "); scanf("%d", &x); arr2D[i][j] = x; } } for(i = 0; i < row; ++i){ printf("\n"); for(j = 0; j < col; ++j) printf("%d\t", arr2D[i][j]); } return 0; }
输出
运行代码并检查其输出:
Enter number of rows & columns of 2-D array: 2 3 Enter a number: 10 Enter a number: 20 Enter a number: 30 Enter a number: 40 Enter a number: 50 Enter a number: 60 10 20 30 40 50 60
示例2
以下代码声明一个变长的一维数组,并用递增的数字填充它:
#include <stdio.h> int main(){ int n; printf("Enter the size of the array: \n"); scanf("%d", &n); int arr[n]; for(int i = 0; i < n; i++) arr[i] = i+1; printf("The array elements are: "); for(int i = 0; i < n; i++) printf("%d ", arr[i]); return 0; }
输出
运行代码并检查其输出:
Enter the size of the array: 5 The array elements are: 1 2 3 4 5 ....
示例3
以下代码使用来自`stdlib.h`头文件的`srand()`和`rand()`函数,用随机生成的数字填充变长数组。
#include <stdio.h> #include <stdlib.h> #include <time.h> void oneDArray(int length, int a[length]); // function prototype void twoDArray(int row, int col, int a[row][col]); // function prototype int main(){ int i, j; // counter variable int size; // variable to hold size of one dimensional array int row, col; // number of rows & columns of two D array srand(time(NULL)); printf("Enter the size of one-dimensional array: "); scanf("%d", &size); printf("Enter the number of rows & columns of 2-D array:\n"); scanf("%d %d", &row, &col); // declaring arrays int arr[size]; // 2-D array int arr2D[row][col]; // one dimensional array for(i = 0; i < size; ++i){ arr[i] = rand() % 100 + 1; } // two dimensional array for(i = 0; i < row; ++i){ for(j = 0; j < col; ++j){ arr2D[i][j] = rand() % 100 + 1; } } // printing arrays printf("One-dimensional array:\n"); // oneDArray(size, arr); for(i = 0; i < size; ++i) printf("a[%d]: %d\n", i, arr[i]); printf("\nTwo-dimensional array:\n"); // twoDArray(row1, col1, arr2D); for(i = 0; i < row; ++i){ printf("\n"); for (j = 0; j < col; ++j) printf("%5d", arr2D[i][j]); } }
输出
运行代码并检查其输出:
Enter the size of one-dimensional array: 5 Enter the number of rows & columns of 2-D array: 4 4 One-dimensional array: a[0]: 95 a[1]: 93 a[2]: 4 a[3]: 52 a[4]: 68 Two-dimensional array: 92 19 79 23 56 21 44 98 8 22 89 54 93 1 63 38
锯齿数组
锯齿数组是两个或多个具有相同数据类型但长度可变的数组的集合。在C语言中,锯齿数组的概念是借助于数组指针实现的。
锯齿数组由下图表示:
示例
在这个程序中,我们声明了三个大小不同的单维数组,并将它们的指针存储在一个指针数组中,该指针数组充当锯齿数组。
#include <stdio.h> int main(){ int a[] = {1,2}; int b[] = {3,4,5}; int c[] = {6,7,8,9}; int l1 = sizeof(a)/sizeof(int), l2 = sizeof(b)/sizeof(int), l3 = sizeof(c)/sizeof(int); int *arr[] = {a,b,c}; int size[] = {l1, l2, l3}; int *ptr; int i, j, k = 0; for(i = 0; i < 3; i++){ ptr = arr[i]; for(j = 0; j < size[k]; j++){ printf("%d\t", *ptr); ptr++; } printf("\n"); k++; arr[i]++; } return 0; }
输出
运行这段代码时,会产生以下输出:
1 2 3 4 5 6 7 8 9
与堆分配相比,VLA是一种更快、更直接的选择。大多数现代C编译器(如GCC、Clang等)都支持VLA,并且大多数编译器都使用VLA。
广告