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

C 語言字符串指針與字符數組本質區別深度解析

     編輯:關於C

核心區別速覽

特性字符指針 char *p字符數組 char arr[]
存儲內容字符串首地址字符串所有字符
字符串位置常量區(只讀)或堆/棧棧/數據區(可讀寫)
賦值方式p = "str" 合法arr = "str" 非法 (左值錯誤)
修改內容未定義行為 (常量區崩潰)合法,可逐字符修改
sizeof 結果指針大小 (4/8)數組總字節數 (含 \0)

關鍵代碼演示

1. 賦值合法性

char *p = "C Language";   // OK
// p = "New";              // OK,改變指向

char arr[20] = "C Language"; // OK,初始化
// arr = "New";               // 編譯錯誤:左值必須可修改
// 必須用 strcpy/逐字符賦值

2. 修改內容的致命差異

int main() {
    char str1[40] = "hello world!";
    // char *str1 = "hello world!";  // 取消註釋將崩潰
    str1[4] = 'A';        // 數組:合法 → "hellA world!"
    // *str1 = 'A';       // 指針:運行時段錯誤 (SIGSEGV)
    printf("%s\n", str1);
    return 0;
}

3. 常量區與可讀寫區

  • char *p = "abc":編譯器在只讀數據段創建字符串常量,p 指向其首地址。嘗試修改觸發硬件異常;
  • char a[] = "abc":編譯器在棧/數據段分配數組,並將常量區內容複製進數組。數組擁有獨立可寫副本。

4. 實戰:字符串轉小寫函數的正確簽名

// 錯誤:傳入字符串常量會崩潰
// void strlower(char *s) { while(*s) *s = tolower(*s); }

// 正確:const 修飾輸入,內部拷貝副本修改
char* strlower(const char *input) {
    char *copy = strdup(input); // 需 free
    for (char *p = copy; *p; ++p) *p = tolower(*p);
    return copy;
}

// 或要求調用者傳入可修改緩衝區
void strlower_inplace(char *buf) { // buf 必須指向可寫內存
    for (; *buf; ++buf) *buf = tolower(*buf);
}

scanf 陷阱與修正

// 錯誤:野指針
char *name;
scanf("%s", name); // 未分配內存,未定義行為

// 修正 1:用數組
char name[20];
scanf("%19s", name);

// 修正 2:動態分配
char *name = malloc(50);
scanf("%49s", name);
// 使用後 free(name)

遞歸反轉字符串(教學演示)

void reverse_print(const char *s) {
    if (!*s) return;
    reverse_print(s + 1); // 先遞歸到末尾
    putchar(*s);          // 回溯時輸出,實現反序
}

總結

「指針指向常量,數組擁有副本」是 C 語言字符串處理的分水嶺。牢記:只讀用 const char*,可寫用數組或動態分配,杜絕段錯誤與未定義行為。

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