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 - Main 函数 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 - 指针 vs 数组 C - 字符指针和函数 C - NULL 指针 C - void 指针 C - 悬垂指针 C - 解引用指针 C - Near、Far 和 Huge 指针 C - 指针数组的初始化 C - 指针与多维数组

C 语言中的字符串

C - 字符串 C - 字符串数组 C - 特殊字符

C 语言的结构体和联合

C - 结构体 C - 结构体和函数 C - 结构体数组 C - 自引用结构 C - 查找表 C - 点 (.) 运算符 C - 枚举(或 enum) C - 结构填充和打包 C - 嵌套结构 C - 匿名结构和联合 C - 联合 C - Bit 位字段 C - Typedef

C 语言中的文件处理

C - 输入和输出 C - 文件 I/O(文件处理)

C 语言中的预处理器

C - 预处理器 C - #pragma 编译指示 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),编译器会在堆栈上分配具有自动存储期限的内存。 C99 标准中添加了对 VLA 的支持。

创建可变长度数组

创建可变长度数组的语法如下 -

void arr_init(int length){

   int arr[length];

   //code using arr;

};

示例

以下示例演示了如何创建可变长度数组 -

#include <stdio.h>

int main(){

    int i, j;
    int size; // 用于保存一维数组大小的变量

   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
", 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:
");
   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("
");
      for(j = 0; j < col; ++j)
         printf("%d	", 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: 
");
   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]); 

// 函数原型
void twoDArray(int row, int col, int a[row][col]);

// 函数原型
int main(){

    int i, j;
    
    // 计数器变量
    int size;
    
    // 保存一维数组大小的变量
    int row, col;
    
    // 二维数组的行数和列数
   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:
");
   scanf("%d %d", &row, &col);

    // 声明数组
    int arr[size];
    
    // 二维数组
    int arr2D[row][col];
    
    // 一维数组
    for(i = 0; i < size; ++i){
        arr[i] = rand() % 100 + 1;
    }
    
    // 二维数组
   for(i = 0; i < row; ++i){
      for(j = 0; j < col; ++j){
         arr2D[i][j] = rand() % 100 + 1;
      }
   }

   // 打印数组
   printf("One-dimensional array:
");
   
   // oneDArray(size, arr);
   for(i = 0; i < size; ++i)
   printf("a[%d]: %d
", i, arr[i]);
   printf("
Two-dimensional array:
");
   
   // twoDArray(row1, col1, arr2D);
   for(i = 0; i < row; ++i){
      printf("
");
      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	", *ptr);
         ptr++;
      }
      printf("
");
      k++;
      arr[i]++;
   }
   
   return 0;
}

输出

运行此代码时,将产生以下输出 -

1       2
3       4       5
6       7       8       9

与堆分配相比,VLA 是一种更快速、更直接的选项。大多数现代 C 编译器(例如 GCC、Clang 等)都支持 VLA,并且大多数编译器都使用 VLA。