C語(yǔ)言學(xué)習(xí)3-指針和數(shù)組

C 語(yǔ)言指針與數(shù)組詳解

一、指針的算術(shù)運(yùn)算

1.1 指針加減法原理

指針加減法不是簡(jiǎn)單的數(shù)值加減,而是以數(shù)據(jù)類(lèi)型大小為步長(zhǎng)進(jìn)行移動(dòng)。

#include <stdio.h>

int main() {
    int arr[4] = {1, 2, 3, 4};
    int* p = arr;  // p 指向數(shù)組首元素
    
    printf("初始位置: %d\n", *p);  // 輸出: 1
    
    p += 1;  // 后移一個(gè)元素(實(shí)際移動(dòng) sizeof(int) 字節(jié))
    printf("后移一個(gè)元素: %d\n", *p);  // 輸出: 2
    
    p -= 1;  // 前移一個(gè)元素
    printf("前移一個(gè)元素: %d\n", *p);  // 輸出: 1
    
    return 0;
}

1.2 指針運(yùn)算的內(nèi)存布局

內(nèi)存地址:  1000  1004  1008  1012
數(shù)組元素: [ 1 ] [ 2 ] [ 3 ] [ 4 ]
指針位置:   p    p+1   p+2   p+3

重要p + n 實(shí)際移動(dòng) n * sizeof(數(shù)據(jù)類(lèi)型) 字節(jié)

二、指針與數(shù)組的關(guān)系

2.1 數(shù)組名的本質(zhì)

#include <stdio.h>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    
    // 數(shù)組名就是首元素地址
    printf("arr = %p\n", arr);           // 數(shù)組名地址
    printf("&arr[0] = %p\n", &arr[0]);   // 首元素地址
    printf("兩者相等: %s\n", arr == &arr[0] ? "是" : "否");
    
    // ? 錯(cuò)誤:數(shù)組名是常量,不能修改
    // arr = 10;        // 編譯錯(cuò)誤
    // arr = &some_var; // 編譯錯(cuò)誤
    
    return 0;
}

2.2 指針操作數(shù)組的多種方式

#include <stdio.h>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int *p = arr;  // p 指向數(shù)組首元素
    
    printf("指針p的地址: %p\n", p);
    printf("數(shù)組arr的地址: %p\n", arr);
    
    // 訪(fǎng)問(wèn)數(shù)組元素的等價(jià)方式
    p = arr + 3;        // 指向第4個(gè)元素
    p = &arr[3];        // 同上,指向第4個(gè)元素
    
    // 修改數(shù)組元素的等價(jià)方式
    arr[3] = 10;        // 傳統(tǒng)數(shù)組下標(biāo)方式
    *(arr + 3) = 10;    // 指針?biāo)阈g(shù)方式
    p = arr + 3;
    *p = 10;            // 通過(guò)指針變量方式
    
    return 0;
}

2.3 數(shù)組遍歷的多種方法

#include <stdio.h>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int length = sizeof(arr) / sizeof(arr[0]);
    
    printf("方法1: 傳統(tǒng)下標(biāo)遍歷\n");
    for(int i = 0; i < length; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);
    }
    
    printf("\n方法2: 指針遍歷\n");
    for(int* p = arr; p < arr + length; p++) {
        printf("元素: %d (地址: %p)\n", *p, p);
    }
    
    printf("\n方法3: 指針?biāo)阈g(shù)遍歷\n");
    for(int i = 0; i < length; i++) {
        printf("*(arr + %d) = %d\n", i, *(arr + i));
    }
    
    return 0;
}

2.4 ?? 數(shù)組越界警告

#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int *p = arr;
    
    // ? 危險(xiǎn):數(shù)組越界訪(fǎng)問(wèn)
    // *(p + 5) = 99;  // 訪(fǎng)問(wèn)第6個(gè)元素,但數(shù)組只有5個(gè)
    
    // ? 危險(xiǎn):負(fù)索引
    // *(p - 1) = 99;   // 訪(fǎng)問(wèn)數(shù)組之前的內(nèi)存
    
    // ? 安全:始終檢查邊界
    int index = 5;
    if (index >= 0 && index < 5) {
        *(p + index) = 99;
    } else {
        printf("錯(cuò)誤:數(shù)組索引 %d 越界!\n", index);
    }
    
    return 0;
}

三、指針數(shù)組

3.1 什么是指針數(shù)組?

指針數(shù)組是一個(gè)數(shù)組,其中的每個(gè)元素都是指針類(lèi)型。

#include <stdio.h>

int main() {
    // 定義三個(gè)整型變量
    int a1 = 10, a2 = 20, a3 = 30;
    
    // 定義指針數(shù)組 - 包含3個(gè)int*類(lèi)型的元素
    int *pointerArray[3];
    
    // 為指針數(shù)組元素賦值(存儲(chǔ)變量的地址)
    pointerArray[0] = &a1;  // 存儲(chǔ)a1的地址
    pointerArray[1] = &a2;  // 存儲(chǔ)a2的地址  
    pointerArray[2] = &a3;  // 存儲(chǔ)a3的地址
    
    return 0;
}

3.2 指針數(shù)組的初始化與使用

#include <stdio.h>

int main() {
    int a1 = 10, a2 = 20, a3 = 30;
    
    // 方法1: 定義時(shí)直接初始化
    int *pointerArray[] = {&a1, &a2, &a3};
    
    // 計(jì)算數(shù)組元素個(gè)數(shù)
    int count = sizeof(pointerArray) / sizeof(pointerArray[0]);
    
    printf("指針數(shù)組遍歷:\n");
    for (int i = 0; i < count; i++) {
        printf("pointerArray[%d] = %p, *pointerArray[%d] = %d\n", 
               i, pointerArray[i], i, *pointerArray[i]);
    }
    
    return 0;
}

3.3 指針數(shù)組的實(shí)用示例

#include <stdio.h>

int main() {
    int x = 100, y = 200, z = 300;
    
    // 指針數(shù)組存儲(chǔ)不同變量的地址
    int *numbers[] = {&x, &y, &z};
    int count = sizeof(numbers) / sizeof(numbers[0]);
    
    // 通過(guò)指針數(shù)組修改變量值
    printf("修改前的值:\n");
    for (int i = 0; i < count; i++) {
        printf("第%d個(gè)值: %d\n", i, *numbers[i]);
    }
    
    // 通過(guò)指針數(shù)組修改所有值
    for (int i = 0; i < count; i++) {
        *numbers[i] *= 2;  // 每個(gè)值乘以2
    }
    
    printf("\n修改后的值:\n");
    for (int i = 0; i < count; i++) {
        printf("第%d個(gè)值: %d\n", i, *numbers[i]);
    }
    
    return 0;
}

3.4 字符串指針數(shù)組(常用場(chǎng)景)

#include <stdio.h>

int main() {
    // 字符串指針數(shù)組 - 常用于命令行參數(shù)處理
    const char *fruits[] = {
        "Apple",
        "Banana", 
        "Cherry",
        "Date"
    };
    
    int count = sizeof(fruits) / sizeof(fruits[0]);
    
    printf("水果列表:\n");
    for (int i = 0; i < count; i++) {
        printf("%d. %s\n", i + 1, fruits[i]);
    }
    
    return 0;
}

四、關(guān)鍵概念總結(jié)

4.1 指針與數(shù)組的區(qū)別

特性 數(shù)組 指針
類(lèi)型 數(shù)據(jù)集合 地址變量
內(nèi)存 連續(xù)分配 存儲(chǔ)地址值
賦值 元素逐個(gè)賦值 直接地址賦值
修改 數(shù)組名不可修改 指針值可修改

4.2 安全使用指南

? 推薦做法:

// 1. 使用sizeof計(jì)算數(shù)組長(zhǎng)度
int arr[] = {1, 2, 3, 4, 5};
int length = sizeof(arr) / sizeof(arr[0]);

// 2. 邊界檢查
if (index >= 0 && index < length) {
    // 安全訪(fǎng)問(wèn)
}

// 3. 指針遍歷時(shí)明確終止條件
for (int *p = arr; p < arr + length; p++) {
    // 安全遍歷
}

? 避免做法:

// 1. 數(shù)組越界
arr[10] = 5;        // 危險(xiǎn)!

// 2. 未初始化的指針訪(fǎng)問(wèn)
int *p;
*p = 10;            // 危險(xiǎn)!

// 3. 錯(cuò)誤的指針運(yùn)算
p = arr;
p += 100;           // 危險(xiǎn)!

4.3 實(shí)用技巧

// 計(jì)算數(shù)組長(zhǎng)度的宏
#define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof((arr)[0]))

// 安全訪(fǎng)問(wèn)宏
#define SAFE_ACCESS(arr, idx) \
    ((idx) >= 0 && (idx) < ARRAY_LENGTH(arr) ? (arr)[(idx)] : 0)

int main() {
    int numbers[] = {1, 2, 3, 4, 5};
    
    // 安全使用
    for (int i = 0; i < ARRAY_LENGTH(numbers); i++) {
        printf("%d ", SAFE_ACCESS(numbers, i));
    }
    
    return 0;
}

掌握指針與數(shù)組的關(guān)系是C語(yǔ)言編程的核心基礎(chǔ),正確使用它們可以編寫(xiě)出高效且安全的代碼!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容