12. C语言 数组与指针(深入理解)

本章目录:


前言

在 C 语言中,数组是一种重要的数据结构,它可以存储一系列相同类型的数据。本文将从基础讲起,结合读者笔记和实际应用,全面解析数组的用法及其高级特性。


1. 什么是数组?

数组是一种顺序存储结构 ,用于存储相同数据类型的多个值。它通过连续的内存单元表示这些值。数组的索引从 0 开始,最高索引为 数组大小 - 1

例如:

c 复制代码
int numbers[5] = {1, 2, 3, 4, 5};

这里 numbers 是一个包含 5 个整数的数组,其内存布局如下:

索引
0 1
1 2
2 3
3 4
4 5

2. 数组的声明与初始化

声明数组

数组声明的语法为:

c 复制代码
type arrayName[arraySize];
  • type:元素类型,如 intdouble
  • arraySize:数组大小,必须是正整数。

示例:

c 复制代码
double balance[10]; // 一个可以存储 10 个 double 类型数据的数组

初始化数组

数组可以在声明时初始化,方法有两种:

  1. 显式初始化
c 复制代码
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
  1. 隐式大小推导
c 复制代码
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};

如果未显式初始化,未赋值的元素将根据数据类型被初始化为默认值,例如:

  • int0
  • float0.0
  • char'\0'

3. 访问数组元素

可以通过数组名加索引访问数组元素:

c 复制代码
int nums[5] = {10, 20, 30, 40, 50};
int value = nums[2]; // value = 30

遍历数组

使用 for 循环:

c 复制代码
for (int i = 0; i < 5; i++) {
    printf("%d ", nums[i]);
}

4. 获取数组长度

使用 sizeof 获取长度

数组总大小可以通过 sizeof(array) 获取,单个元素的大小可以通过 sizeof(array[0]) 获取。数组长度计算公式为:

c 复制代码
int length = sizeof(array) / sizeof(array[0]);

示例:

c 复制代码
int nums[] = {1, 2, 3, 4, 5};
int length = sizeof(nums) / sizeof(nums[0]);
printf("数组长度为: %d\n", length); // 输出 5

使用宏定义简化

c 复制代码
#define LENGTH(array) (sizeof(array) / sizeof(array[0]))

调用示例:

c 复制代码
int nums[] = {1, 2, 3, 4, 5};
printf("数组长度为: %d\n", LENGTH(nums));

5. 数组与指针

在 C 中,数组名可以视为指向其首元素的指针,但两者有本质区别。

数组名与指针的区别

特性 数组名 指针变量
表示内容 首元素地址 存储的地址
是否可修改 不可修改 可修改
用于传参 表示指针 可指向任意变量

例如:

c 复制代码
int nums[5] = {1, 2, 3, 4, 5};
int *ptr = nums; // 数组名 nums 表示首元素地址

使用指针操作数组

可以通过指针遍历数组:

c 复制代码
int nums[5] = {1, 2, 3, 4, 5};
int *ptr = nums;

for (int i = 0; i < 5; i++) {
    printf("%d ", *(ptr + i)); // 指针运算
}

6. 多维数组

C 支持多维数组,最常见的是二维数组。其声明和初始化方式如下:

c 复制代码
int matrix[2][3] = {
    {1, 2, 3},
    {4, 5, 6}
};

遍历多维数组

c 复制代码
for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) {
        printf("%d ", matrix[i][j]);
    }
    printf("\n");
}

7. 数组作为函数参数

数组可以通过指针形式传递给函数:

c 复制代码
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
}

int main() {
    int nums[] = {1, 2, 3, 4, 5};
    printArray(nums, sizeof(nums) / sizeof(nums[0]));
    return 0;
}

注意:在函数中无法直接通过 sizeof 获取数组长度,因此需额外传递数组大小。


8. 高级技巧与注意事项

初始化技巧

数组可以通过 {0} 一次性初始化为零:

c 复制代码
int nums[10] = {0};

常见陷阱

  • 字符串数组与字符串指针的区别

    c 复制代码
    char str[] = "Hello";  // 自动追加 '\0'
    char *ptr = "Hello";   // 指向常量字符串
  • 数组变量不可赋值

    c 复制代码
    int nums1[5], nums2[5];
    nums1 = nums2; // 错误,数组名是常量指针

9. 示例:统计超过平均值的学生人数

以下代码示例展示了数组的一个实际应用场景:

c 复制代码
#include <stdio.h>

int main() {
    int scores[100], n, count = 0;
    double sum = 0;

    printf("输入学生人数: ");
    scanf("%d", &n);

    printf("输入每位学生的成绩:\n");
    for (int i = 0; i < n; i++) {
        scanf("%d", &scores[i]);
        sum += scores[i];
    }

    double avg = sum / n;

    for (int i = 0; i < n; i++) {
        if (scores[i] > avg) {
            count++;
        }
    }

    printf("平均分为: %.2f\n", avg);
    printf("超过平均分的人数: %d\n", count);

    return 0;
}

总结

数组是 C 语言中的基础而重要的结构。通过掌握数组的声明、初始化、操作以及与指针的关系,您可以更高效地处理多数据存储和计算的需求。希望本文能够帮助您对 C 数组有更深入的理解!


相关推荐
wefg12 分钟前
【Linux】线程同步与互斥 - 2(线程同步/条件变量/基于阻塞/环形队列的cp模型/线程池/线程安全/读写锁)
linux·开发语言
雨落在了我的手上8 分钟前
C语言之数据结构初见篇(2):顺序表之通讯录的实现(续)
c语言·开发语言·数据结构
小生不才yz9 分钟前
【Makefile 专家之路 | 基础篇】02. 初试锋芒:编写第一个 Makefile 与运行机制深度剖析
linux
【数据删除】34811 分钟前
计算机复试学习笔记 Day41
笔记·学习·算法
上海锟联科技11 分钟前
什么是DAS分布式光纤声波传感系统?原理与应用解析
数据结构·分布式·算法·分布式光纤传感
你这个代码我看不懂12 分钟前
JVM栈、方法区和堆内存
java·开发语言·jvm
河铃旅鹿14 分钟前
在windows电脑上用虚拟机--ubuntu系统部署openclaw并在主机用飞书连接对话的一站式教程
windows·ubuntu·飞书
GIS阵地15 分钟前
一场由Qt5 painter的drawRect引起的血雨腥风
开发语言·qt·gis·qgis
学编程就要猛17 分钟前
JavaEE初阶:多线程案例
java·开发语言
圥忈&&丅佽&&扗虖17 分钟前
打开ubuntu 的22 端口
ubuntu