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

C語言數組賦值陷阱:為什麼 a[i]=b[j] 無法實現數組拷貝?

     編輯:C 語言問答

問題現場還原

int a[5], b[5], i=0, j=0;
// ... 輸入 a 數組 ...
while(i < 5) {
    a[i] = b[j];  // 錯誤賦值方向!
    printf("%d", b[j]);
    i++; j++;
}

現象:無法輸出 b[] 的值,因為 b 數組未初始化,全是垃圾值。

核心錯誤分析

賦值運算符 = 方向是「從右向左」:

  • a[i] = b[j] 意為:將 b[j] 的值賦給 a[i]。
  • 此時 b[j] 未賦值(未初始化的局部數組值不定),導致 a[i] 變成垃圾值,打印 b[j] 也是垃圾值。

正確的數組拷貝方式

方法一:修正賦值方向(逐元素拷貝)

while(i < 5) {
    b[i] = a[i];  // 正確:將 a[i] 賦給 b[i]
    printf("%d ", b[i]);
    i++;
}

方法二:使用標準庫 memcpy(高效、推薦)

#include <string.h> // 或 <stdlib.h>
// ...
memcpy(b, a, sizeof(a)); // 一次性拷貝整個數組
// 然後打印 b
for(i=0; i<5; i++) printf("%d ", b[i]);
  • 優點:代碼簡潔、編譯器優化(通常內聯為指令級拷貝)、不易出錯。
  • 注意:sizeof(a) 在數組定義作用域內有效;若數組退化為指針傳入函數,需顯式傳遞長度。

方法三:結構體包裹實現整體賦值(C語言特性)

struct Arr5 { int v[5]; };
struct Arr5 sa = { .v = {1,2,3,4,5} }, sb;
sb = sa; // 結構體變量之間支持直接整體賦值!
// sb.v 即為拷貝結果
  • 原理:C語言允許同類型結構體變量直接賦值(逐成員拷貝),利用此特性實現數組整體拷貝。

深度補充:為什麼數組不支持直接賦值?

  • 數組在表達式中(除 sizeof、&、_Alignof 外)會退化為指向首元素的指針,失去長度信息。
  • 編譯器無法在編譯期確定運行時指針指向的內存塊大小,故禁止 b = a 這類整體賦值。
  • 結構體不退化,編譯器知曉其完整佈局和大小,故支持整體賦值。

最佳實踐建議

  1. 首選 memcpy/memmove:標準、高效、語義明確。
  2. 小型固定長度數組可用結構體包裹技巧或手寫循環。
  3. 動態數組務必傳遞長度,用 memcpy(dest, src, n * sizeof(int))。
  4. 字符串拷貝用 strcpy/strncpy/strlcpy,注意結束符 \0。
  5. 初始化 vs 賦值:定義時 int b[5] = {0}; 或 int b[5] = {1,2,3,4,5}; 是初始化(允許列表),運行時只能逐元素或 memcpy。

總結

數組拷貝的核心是搞清數據流向:源數組 → 目標數組。原代碼 a[i]=b[j] 方向反了,且源數組 b 未初始化。掌握 memcpy、結構體包裹、循環拷貝三種姿勢,並理解數組退化機制,即可徹底避開此坑。

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