Skip to content
鼓励作者:欢迎打赏犒劳

数组

数组的初始化

  • 在定义数组的同时进行赋值,称为初始化
  • 全局数组若不初始化,编译器将其初始化为零
  • 局部数组若不初始化,内容为随机值
c
int a1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 定义一个数组,同时初始化所有成员变量
int a2[10] = { 1, 2, 3 }; // 初始化前三个成员,后面所有元素都设置为0
int a3[10] = { 0 }; // 所有的成员都设置为0

 // []中不定义元素个数,定义时必须初始化
int a4[] = { 1, 2, 3, 4, 5 }; // 定义了一个数组,有5个成员

演示上述的各种情况

c
#include <stdio.h>

void show_local_array() {
    // 定义一个局部数组,故意不进行初始化
    int random_arr[5]; 

    printf("=== 局部数组 (未初始化) ===\n");
    printf("内存中的垃圾值如下:\n");
    
    for (int i = 0; i < 5; i++) {
        // 注意:这里打印出来的值每次运行可能都不一样!
        // 甚至在同一台电脑上,不同次运行的结果也不同。
        printf("random_arr[%d] = %d\n", i, random_arr[i]);
    }
    printf("\n");
}

void show_global_array() {
    // 全局数组在定义时如果不初始化,默认全是 0
    // 为了演示,我们在函数外部定义,或者在这里定义 static
    static int zero_arr[5]; 

    printf("=== 全局/静态数组 (未初始化) ===\n");
    printf("编译器自动初始化的值如下:\n");
    
    for (int i = 0; i < 5; i++) {
        printf("zero_arr[%d] = %d\n", i, zero_arr[i]);
    }
    printf("\n");
}

int main() {
    // 第一次调用
    show_local_array();
    show_global_array();

    // 为了演示“随机性”,我们可以再调用一次,或者在中间做点其他操作
    // 这里的值很可能和第一次不一样
    printf("--- 再次运行局部数组函数 ---\n");
    show_local_array();

    return 0;
}

结果

c
=== 局部数组 (未初始化) ===
内存中的垃圾值如下:
random_arr[0] = -1505618272
random_arr[1] = 32758
random_arr[2] = 16
random_arr[3] = 0
random_arr[4] = 0

=== 全局/静态数组 (未初始化) ===
编译器自动初始化的值如下:
zero_arr[0] = 0
zero_arr[1] = 0
zero_arr[2] = 0
zero_arr[3] = 0
zero_arr[4] = 0

--- 再次运行局部数组函数 ---
=== 局部数组 (未初始化) ===
内存中的垃圾值如下:
random_arr[0] = 1166014808
random_arr[1] = 110
random_arr[2] = 313592696
random_arr[3] = 39
random_arr[4] = 0

数组赋值和遍历

c
#include <stdio.h>

int main() {
    // 定义了一个数组,名字叫a,有10个成员,每个成员都是int类型
    int a[10]; 
    for (int i = 0; i < 10; i++) {
        a[i] = i; // 给数组赋值
    }

    // 遍历数组,并输出每个成员的值
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");

    return 0;
}

数组长度

c语言真麻烦,啥都是原生手搓。

c
#include <stdio.h>

int main() {
    // 定义一个数组,同时初始化所有成员变量
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 

    // 数组名是一个地址的常量,代表数组中首元素的地址
    printf("a = %p\n", a);
    printf("&a[0] = %p\n", &a[0]);

    int n = sizeof(a);     // 数组占用内存的大小,10个int类型,10 * 4  = 40
    int n0 = sizeof(a[0]); // 数组第0个元素占用内存大小,第0个元素为int,4
    int num = n / n0;      // 元素个数
    printf("n = %d, n0 = %d, num = %d\n", n, n0, num);

    return 0;
}

或者定义宏

c
#include <stdio.h>
#define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof((arr)[0]))

int main() {
    // 定义一个数组,同时初始化所有成员变量
    int a[] = {1, -2, 3, -4, 5, -6, 7, -8, -9, 10};
    int num = ARRAY_LENGTH(a);
    // 假设第0个元素就是最大值
    int temp = a[0];
    for (int i = 0; i < num; i++) {
        // 如果有元素比临时的最大值大,就交换值
        if (a[i] > temp) {
            temp = a[i];
        }
    }
    printf("数组中最大值为:%d\n", temp);

    return 0;
}

通过指针操作数组元素

c
#include <stdio.h>

int main() {
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int i = 0;
    int n = sizeof(a) / sizeof(a[0]);

    for (i = 0; i < n; i++) {
        // * 和 [] 效果一样,都是操作指针所指向的内存
        // printf("%d, ", a[i]);
        printf("%d, ", *(a + i));
    }
    printf("\n");

    // 定义一个指针变量保存a的地址
    int *p = a; 
    for (i = 0; i < n; i++) {
        // printf("%d, ", p[i]);
        printf("%d, ", *(p + i));
    }
    printf("\n");

    return 0;
}

指针数组

c
#include <stdio.h>

int main() {
    // 指针数组
    int *p[3];
    int a = 1;
    int b = 2;
    int c = 3;

    // 指针变量赋值
    p[0] = &a;
    p[1] = &b;
    p[2] = &c;

    for (int i = 0; i < sizeof(p) / sizeof(p[0]); i++) {
        printf("%d, ", *(*(p + i)));
        // printf("%d, ", *(p[i]));
    }
    printf("\n");

    return 0;
}

数组名做函数参数

数组名做函数参数,函数的形参本质上就是指针

c
#include <stdio.h>

// 下面3种写法完全等价
// void print_arr(int a[10], int n)
// void print_arr(int a[], int n)
void print_arr(int *a, int n) {
    int i = 0;
    for (i = 0; i < n; i++) {
        printf("%d, ", a[i]);
    }
    printf("\n");
}

int main() {
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int n = sizeof(a) / sizeof(a[0]);

    // 数组名做函数参数
    print_arr(a, n);

    return 0;
}

第二个示例

c
#include <stdio.h>
#include <stdint.h>

// 打印数组, 三种写法皆可
//void print_arr(int arr[5], int size)
//void print_arr(int arr[], int size)
void print_arr(int * arr, int size) {
	
	// 对参数arr使用sizeof, 只会得到int指针的大小(固定为8)
	// [警告] 'sizeof' on array function parameter 'arr' will return size of 'int *' [-Wsizeof-array-argument]
	printf("数组字节数:%d\n", sizeof(arr));
	
	// 数组以参数形式传递时,传递过来的是首元素地址, 
    // 数组的长度信息丢失了,sizeof(arr)得到的是指针的大小,需要将数组的个数size从外部传进来
	for (int i = 0; i < size; i++) {
		printf("%d -> %d\n", i, *(arr + i));
	}

}

int main() {

	// 需求:编写一个函数,按格式打印数组
	int arr[] = {10, 20, 30, 40, 50};

	// 在声明函数的代码块,通过sizeof(arr)才能得到数组的字节占用数
	int size = sizeof(arr) / sizeof(arr[0]);
	
	print_arr(arr, size);

	return 0;
}

多维数组

c
#include <stdio.h>
#include <stdint.h>

// 二维数组,用于保存多组数据
int main() {
	// 一维数组:元素是数值
	int stu1[] = {18, 180, 100, 99};
	int stu2[] = {19, 170,  98, 99};
	int stu3[] = {20, 160,  90, 92};


	// 二维数组:元素是一维数组的指针
    // stus 是一个指针数组,每个元素指向一个一维数组。
    int * stus_arr[] = {stu1, stu2, stu3};

	// 第一个[]表示包含了几个一维数组
	// 第二个[]表示每个一维数组有几个元素
	int stus[][4] = {
		{18, 180, 100, 99},
		{19, 170,  98, 99},
		{20, 160,  90, 92},
	};

	printf("%d\n", stus[1][2]);
	printf("%d\n", *(stus[1] + 2));

	return 0;
}

如有转载或 CV 的请标注本站原文地址