首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言指針與字符串進階:動態內存、遍歷與常見陷阱

     編輯:關於C語言

指針是 C 語言的靈魂,字符串則是指針應用的最高頻場景。本文結合動態內存分配、指針算術、字符串構建與遍歷,通過兩個完整案例演示正確用法並揭露經典坑點。

案例一:動態分配構建字母表字符串

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char *ptr = malloc(27 * sizeof(char));  // 26 字母 + '\0'
    if (!ptr) {
        puts("內存分配失敗!");
        return EXIT_FAILURE;
    }
    
    ptr[26] = '\0';  // 先寫終止符,防衛性編程
    
    char *p = ptr;   // 工作指針,保護 ptr 不被移動
    for (int ch = 'A'; ch <= 'Z'; ++ch) {
        *p++ = (char)ch;  // 寫入並後移
    }
    
    printf("ptr 內容: %s\n", ptr);  // ABCDEFGHIJKLMNOPQRSTUVWXYZ
    
    // 重置 p 以便再次遍歷或釋放
    p = ptr;
    puts(p);  // 等價於 puts(ptr)
    
    free(ptr);  // 歸還堆內存
    ptr = NULL; // 避免懸空指針
    return EXIT_SUCCESS;
}

關鍵點解析

  1. malloc 返回 void*:C 語言隱式轉換為目標指針類型,無需強轉(C++ 需強轉)。
  2. 分配失敗檢查:if (!ptr) 是專業代碼必備。
  3. 工作指針模式:用 p 遍歷,保持 ptr 指向塊首,便於 free。
  4. 先寫 '\0':即便後續邏輯提前退出,字符串也是合法的空串。
  5. free 後置 NULL:防止二次釋放或誤用。

案例二:字符串字面量 vs 動態分配 vs 棧數組

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    // 1. 字符串字面量 —— 存儲在只讀區,不可修改
    char *msg1 = "I am mini, I am very well!";
    // msg1[0] = 'H'; // 錯誤:段錯誤(只讀內存)
    
    // 2. 棧上字符數組 —— 可修改,生命週期隨作用域結束
    char msg2[] = { "I am mini, I am very well!" };
    msg2[0] = 'H'; // 合法
    
    // 3. 動態分配 —— 可修改,手動管理生命週期
    char *msg3 = malloc(100);
    if (msg3) {
        strcpy(msg3, "Dynamic string");
        msg3[0] = 'H'; // 合法
        free(msg3);
    }
    
    // 4. 不同類型指針的 malloc 模式
    int *arr = malloc(50 * sizeof(int));      // 50 個 int
    float *farr = malloc(10 * sizeof(float)); // 10 個 float
    char *single = malloc(1);                 // 1 字節
    *single = 'x';
    
    free(arr); free(farr); free(single);
    return 0;
}

核心概念總結表

概念說明典型錯誤
字符串結束符\0 (ASCII 0),標記字符串結尾忘記分配/寫入 \0,導致越界讀取
指針算術p++ 移動 sizeof(*p) 字節對 void* 算術(GNU 允許但非標準)
字面量 vs 數組char *s = "abc"; 指向只讀區;char s[] = "abc"; 棧上拷貝嘗試修改字面量導致崩潰
malloc 參數總字節數 = 元素數 × sizeof(類型)只寫元素數,忘記乘 sizeof

避坑指南

  • 永不 對 void* 做算術(除非強轉為 char*)。
  • 永不 free 非 malloc/calloc/realloc 返回的指針(如字面量、棧地址)。
  • 永不 使用已 free 的指針(置 NULL 即可避免)。
  • 字符串操作優先用 snprintf、strncpy 等帶長度限制的安全版本。

指針與字符串的舞蹈,核心在於所有權清晰、邊界檢查、生命週期同步。熟練掌握動態內存模式,是從「能跑通」進化到「工業級可靠」的分水嶺。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved