C语言学习笔记六(指针)

一、数组的基本概念

  1. 定义:数组是相同类型数据元素的集合,这些元素在内存中连续存储

  2. 特点

    • 所有元素具有相同的数据类型

    • 元素在内存中是连续存储的

    • 通过下标(索引)访问元素,下标从0开始

二、一维数组的声明和初始化

1. 数组声明

数据类型 数组名[数组长度];

示例:

int numbers[5];      // 声明一个包含5个整数的数组
float scores[10];    // 声明一个包含10个浮点数的数组
char letters[26];    // 声明一个包含26个字符的数组

2. 数组初始化

(1) 完全初始化:

int numbers[5] = {1, 2, 3, 4, 5};

(2) 部分初始化(未初始化的元素自动设为0):

int numbers[5] = {1, 2};  // 等价于 {1, 2, 0, 0, 0}

(3) 不指定长度初始化(编译器自动计算长度):

int numbers[] = {1, 2, 3, 4, 5};  // 数组长度为5

(4) C99新增的指定初始化方式:

int numbers[5] = {[2] = 3, [4] = 5};  // 其他元素为0

 强调:指针字节数与指针指向类型无关

16位系统:16 / 8 = 2字节;32位系统:32 / 8 = 4字节;64 / 8 = 8字节

三、数组元素的访问

  1. 通过下标访问:

    int numbers[5] = {10, 20, 30, 40, 50};
    int x = numbers[0];  // 访问第一个元素,x=10
    numbers[2] = 100;    // 修改第三个元素为100
  2. 数组下标范围是0到(数组长度-1),越界访问是未定义行为

四、数组在内存中的存储

  1. 数组元素在内存中是连续存储的

  2. 数组名代表数组首元素的地址

  3. 计算数组大小:

    int numbers[5];
    size_t size = sizeof(numbers);        // 整个数组的字节大小
    size_t element_count = sizeof(numbers) / sizeof(numbers[0]);  // 元素个数

五、数组与指针的关系

  1. 数组名在大多数情况下会转换为指向其首元素的指针

  2. 指针可以像数组一样使用下标:

    int numbers[5] = {1, 2, 3, 4, 5};
    int *ptr = numbers;
    printf("%d", ptr[2]);  // 输出3
  3. 数组名不是指针的例外情况:

    • 使用sizeof运算符时

    • 使用&运算符时

    • 作为字符串字面量初始化字符数组时

六、数组作为函数参数

  1. 数组作为函数参数时,实际上传递的是数组首元素的地址

  2. 常用传递方式:

    // 方式1:使用数组形式声明参数
    void func(int arr[], int size);
    
    // 方式2:使用指针形式声明参数
    void func(int *arr, int size);
  3. 调用示例:

    int numbers[5] = {1, 2, 3, 4, 5};
    func(numbers, 5);

七、常见数组操作

1. 遍历数组

int numbers[5] = {1, 2, 3, 4, 5};
for(int i = 0; i < 5; i++) {
    printf("%d ", numbers[i]);
}

 2. 数组赋值

int src[5] = {1, 2, 3, 4, 5};
int dest[5];

// 必须逐个元素赋值
for(int i = 0; i < 5; i++) {
    dest[i] = src[i];
}

 3. 查找元素

int findValue(int arr[], int size, int value) {
    for(int i = 0; i < size; i++) {
        if(arr[i] == value) {
            return i;  // 返回下标
        }
    }
    return -1;  // 未找到
}

4. 排序数组(冒泡排序示例)

void bubbleSort(int arr[], int size) {
    for(int i = 0; i < size-1; i++) {
        for(int j = 0; j < size-i-1; j++) {
            if(arr[j] > arr[j+1]) {
                // 交换
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

八、注意

  1. 数组越界:C语言不检查数组下标是否越界,越界访问可能导致程序崩溃或不可预测行为

  2. 数组长度:数组长度必须是编译时常量(C99之前)或常量表达式

  3. 数组名不可修改:数组名不是左值,不能赋值

  4. 数组大小固定:声明后大小不能改变

  5. 数组与指针的区别

    • sizeof(数组名)返回整个数组的大小

    • sizeof(指针)返回指针本身的大小

    • &数组名得到的是指向整个数组的指针

    • 指针可以重新赋值,数组名不能

九、C99新增特性

  1. 变长数组(VLA):

    int n = 10;
    int arr[n];  // C99支持,但C11改为可选特性
  2. 指定初始化器:

    int arr[10] = {[3] = 100, [7] = 200};

 十、应用示例

#include <stdio.h>

#define SIZE 5

// 函数原型
void printArray(int arr[], int size);
double getAverage(int arr[], int size);

int main() {
    // 初始化数组
    int numbers[SIZE] = {10, 20, 30, 40, 50};
    
    // 打印数组
    printf("数组元素: ");
    printArray(numbers, SIZE);
    
    // 计算平均值
    double avg = getAverage(numbers, SIZE);
    printf("平均值: %.2f\n", avg);
    
    return 0;
}

// 打印数组函数
void printArray(int arr[], int size) {
    for(int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

// 计算平均值函数
double getAverage(int arr[], int size) {
    double sum = 0;
    for(int i = 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值