如果我在一行定義char* a, b; 這樣a是指針,b是字元型變數,把*貼著數據類型寫看著不容易亂嗎?


char *a;

char b;

寫成這樣不好嗎?為什麼要寫在一起。


這個是可以調靠左還是靠右的,而且這個跟甜咸豆腐腦一樣,不是原則問題,是黨爭問題。靠左意思是把char*看做類型,靠右是因為*是指針聲明符,實際上兩種都有道理。

但是我還是要說,靠右的都是異端(


我認為應該規範為

char * a ;


我不知道題主用的啥編輯器,但絕大部分編輯器和教材(比如某primer)都會寫成char *a 的形式,主要是因為char被認為是基本類型,而a是經過*的「運算」才得到char的。從運算的角度看,a和*的關係更緊密。

比如char (*(*a)[])() 這個亂七八糟的聲明,你無法把a的類型看成一個整體。唯一能分開的就是基本類型char和這一坨「運算」了,為了保持一致性,也體現C的這種聲明邏輯,編輯器一般會選擇char *a這種基本類型與其餘部分分開的寫法。事實上,你想要讀懂這種聲明,依賴的也只有「運算」的邏輯,按照運算符的優先順序一步步推導出類型。

綜上所述,指針靠右其實更貼合c的設計本意。如果題主的編輯器靠左,看看是否有相應的設置。很多格式化器都有指針靠左還是右的設置的。

ps 上面的例子,a首先跟*結合,所以a是指針,然後跟[]結合,所以指針指向數組。然後跟*結合,所以數組的元素是指針。然後跟最右側()結合,所以指向的是函數,最後只剩char,所以返回值是char。

當然,可能C的發明者自己也知道這種聲明邏輯弄複雜了太反人類,所以發明了typedef.....

pps 其實函數和變數的聲明沒有本質區別,把()看成一個運算符即可。如果你喜歡,甚至可以用「聲明一個變數的方式」聲明一個函數(雖說本質就是一個方式。。。

比如

typedef int func_t(int);

func_t myfunc;//這是個函數聲明

同理,你甚至可以把函數和變數聲明在一起。。只要返回值和變數類型是同一個基本類型。。


這個是書寫規範,不是編譯器編譯規範。隨便怎麼寫都行,只是後者容易邏輯錯誤而已


c語言中的類型聲明,我把他叫做推斷式的類型聲明。

char *a;

意為聲明一個*a為char的a,那麼a就是char*類型的。

同理

char a[10];

意為聲明一個a[n]為char的a,那麼a就是char[]類型的。

其實挺彆扭的,具體編譯器怎麼理解我也不知道,總之這麼歸納方便記憶。

至於規範問題,我覺得*靠近變數名,那就是清晰上面說的聲明邏輯。*靠近類型那就是清晰變數類型,當然這種清晰是對單個變數聲明來說。


不知道題主用的是什麼編譯/編輯器,至少在vscode上,char* a是會被規範成char *a


所以我自己寫格式化工具


現在主流的代碼格式化工具 ClangFormat 有一個屬性叫做 PointerAlignment,它可以設置三種值 LeftRightMiddle。這三種值格式化出來的效果分別是:

char* a;
char *a;
char * a;

實際上這三種寫法各有優劣,我個人喜歡用 char* a 的方式,因為 char* 是一個整體的類型說明符。(至於一行內聲明多個指針,或指針與非指針同時聲明的情況,分開寫就好了。)

這個知乎已經有討論了。基本結論就是,C++程序員更喜歡左對齊,而C程序員更喜歡右對齊。

C/C++ 里指針聲明為什麼通常不寫成 int* ptr 而通常寫成 int *ptr ??

www.zhihu.com圖標

C語言一般放變數名旁邊,是因為星號在這裡是個運算符,多個指針變數一起的時候,需要挨個寫出來,所以:

char *a, *b, c;

其中 ab 都是指針,而 c 只是一個普通的變數;

但像是C#這種帶指針的編程語言一般會把這個符號當成類型的一部分(可以理解為特殊類型的標記符號),所以:

char* a, b, c;

這又是表示 abc 都是 char* 類型。

主要還是因為C語言的指針會有複雜的類型標記模型:

char (*p)(char *);

類似於這種。


char* a,b; 在C/C++ 中 b 是char 型說明應該寫成

char *a,b;

本人不提倡, 這樣代碼格式化,也堅決抵制 「tab轉換成四個空格「 的規範。(哈哈,文明用語)


推薦閱讀:
相关文章