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

C 語言面試題精選:const 指針辨析與 sizeof 陷阱全解

     編輯:關於C語言

題目一:三種 const 指針聲明的區別


char * const p1;     // (1)
char const * p2;     // (2)
const char * p3;     // (3)

口訣:const 修飾右邊的類型,或左邊的類型(無右邊時)

從變量名向左讀:

聲明讀法指針可改?內容可改?必須初始化?
char * const p1p1 是 const 指針,指向 char否是是
char const * p2p2 是指針,指向 const char是否否
const char * p3p3 是指針,指向 const char是否否

(2) 和 (3) 完全等價,const 在 * 左邊修飾基類型。

代碼驗證


char c1 = 'a', c2 = 'b';

// (1) 指針常量
char * const p1 = &c1;
// p1 = &c2; // 錯誤:不能改指向
*p1 = 'c';   // 正確:可改內容
c1 = 'd';    // 正確

// (2)/(3) 常量指針
const char *p2 = &c1;
p2 = &c2;    // 正確:可改指向
// *p2 = 'c'; // 錯誤:不能通過指針改內容
c1 = 'e';    // 正確:可通過原變量改

題目二:sizeof 在函數參數與字符串中的陷阱


void UpperCase(char str[]) {  // 實際為 char *str
    for (size_t i = 0; i < sizeof(str)/sizeof(str[0]); ++i) // 錯誤!
        if (str[i] >= 'a' && str[i] <= 'z') str[i] -= 'a' - 'A';
}

char str[] = "aBcDe";
cout << sizeof(str)/sizeof(str[0]) << endl; // 正確:6(含 \0)
UpperCase(str);

核心問題

  1. 函數參數退化:char str[] 在參數中**等價於** char *str,失去數組長度信息
  2. sizeof(str) 在函數內返回**指針大小**(4 或 8),而非數組長度
  3. 主函數中 str 是真正數組,sizeof 返回整個數組字節數

正確做法


// 1. 顯式傳長度
void UpperCase(char *str, size_t len) { ... }

// 2. C++ 用引用保持數組類型(僅限固定長度)
template
void UpperCase(char (&str)[N]) { ... }

// 3. 字符串專用:strlen
void UpperCase(char *str) {
    for (size_t i = 0, n = strlen(str); i < n; ++i) ...
}

sizeof 運算符完整規則

操作數結果備註
類型 sizeof(int)類型大小需括號
變量 sizeof x變量類型大小無括號可
字面量 sizeof "abc"4(含 \0)字符串字面量是數組
數組名(定義處)整個數組字節數不退化
數組參數指針大小已退化
動態分配指針指針大小無法獲取堆塊大小

優先級提醒

sizeof 優先級極高(同 *、&、++),屬於一元運算符。
sizeof int * p 解析為 (sizeof int) * p,若想對指針取 sizeof 需 sizeof (int *) 或 sizeof *p。

總結

const 位置決定修飾對象,**數組參數退化為指針**是 C 語言最大的「坑」之一。面試必考,工程中慣用 指針+長度 或 std::span/string_view (C++20) 避免丟失長度信息。

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