前言
我們都知道const可以修飾數(shù)據(jù)類型,例如:
int *const p表示定義了一個(gè)常量指針;
const int* p表示定義了一個(gè)指向常量的指針;
關(guān)于常量指針以及指向常量的指針的區(qū)別可以參考筆者的另一篇文章C語言-常量指針與指向常量的指針.
我們也知道可以使用typedef關(guān)鍵字來定義數(shù)據(jù)類型的別名,例如:
typedef int MyInt
typedef struct student student_t
typedef void (*my_func)(void);
但是當(dāng)我們使用typedef關(guān)鍵字定義指針類型的別名時(shí),在前方加入修飾符const可能會(huì)和我們實(shí)際想的情況不一樣.
#include <stdio.h>
void func(const int* cfg) {
return;
}
int main(void) {
const int data = 10;
func(&data);
return 0;
}
在這個(gè)例子中,func的參數(shù)為const int*的指針類型,然后我們定義了一個(gè)const int類型的data,將data的地址作為參數(shù)傳遞.
然后我們編譯,沒有報(bào)錯(cuò).
說明const修飾的數(shù)據(jù)取地址轉(zhuǎn)為指針時(shí),默認(rèn)轉(zhuǎn)成了一個(gè)指向常量的指針.
那么我們稍微修改一下代碼,使用typedef定義一個(gè)別名來指代int*:
#include <stdio.h>
typedef int* int_ptr_t;
/* const int_ptr_t 被轉(zhuǎn)換成了 int *const, 變成了一個(gè)指針常量 */
void func(const int_ptr_t cfg) {
return;
}
int main(void) {
const int data = 10;
/* &data 被轉(zhuǎn)換成了 const int*, 是一個(gè)指向常量的指針 */
func(&data);
return 0;
}
在上述代碼中,我們使用typedef定義了一個(gè)別名int_ptr_t,用來指代int*這個(gè)指針類型.然后函數(shù)的參數(shù)為const int_ptr_t.
然后我們編譯一下,出現(xiàn)了警告:
╰─? gcc main.c
main.c: In function ‘main’:
main.c:14:10: warning: passing argument 1 of ‘func’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
14 | func(&data);
| ^~~~~
main.c:6:27: note: expected ‘int_ptr_t’ {aka ‘int * const’} but argument is of type ‘const int *’
6 | void func(const int_ptr_t cfg) {
這個(gè)警告的類型是[-Wdiscarded-qualifiers]丟失的限定符,說我們func函數(shù)放棄指針目標(biāo)類型中的const限定符, 參數(shù)預(yù)期要的是int_ptr_t {aka ‘int * const’}這個(gè)類型,但是實(shí)際傳入了‘const int *’.
實(shí)際傳入的類型確實(shí)是const int*,這個(gè)也是我們期望的類型,但是函數(shù)的參數(shù)怎么變成了int * const?
這是因?yàn)槲覀?code>typedef關(guān)鍵字定義別名并不是像define一樣進(jìn)行替換.
我們的int_ptr_t指代的是int*指針類型,const int_ptr_t修飾的應(yīng)該是這個(gè)指針,所以轉(zhuǎn)變成了常量指針int *const.