C語言各種符號的使用介紹上篇

1、註釋符號

1.1 註釋的基本註意事項

為瞭更好的演示我們下面的代碼會在 Linux 平臺下演示( \ 為續行符):

這段代碼,哪一行是有問題的呢?

這裡可能有小夥伴就有疑問瞭,為什麼隻有這一行出瞭問題呢?我們知道註釋在預處理階段就被編譯器識別出來瞭,這裡我們可以用 Linux 的一個指令:gcc -E test.c -o test.i這樣就是對test.c 程序進行翻譯,最終把預處理的結果保留下來,接著就可以用 vim 打開我們的預處理結果文件瞭。

最終我們可以得出這樣一個結論:註釋被替換本質上是被替換成空格!

這裡我們要再提一個簡單的點,C語言註釋無法被嵌套,/* 總是與最近的 */ 匹配,感興趣的小夥伴可以去測試下:

int main()
{
    /*
    /*printf("hello world");
    printf("hello world");*/
    */
    return 0;
}

這裡還有一個有趣的代碼,如果用C語言的註釋的話,如果隻出現瞭一個 /* 找不到下面的 */ 的話,那麼他就會默認下面所有代碼都被註釋!

int main()
{
    int x = 10;
    int y = 5;
    int ret = 0;
    int* p = &y;
    ret = y/*p;
    return 0;
}

那麼如何解決上面這種情況呢?

在 / 與 * 中加上空格: ret = y / *p;

把 *p 用括號括起來: ret = y / (*p);

推薦第二種,因為看起來會更直觀

1.2 如何寫出好的註釋

[ 建議1 ] 註釋應該準確易懂,不能有爭議性,錯誤的註釋反而有害。

[ 建議2 ] 要保證註釋與代碼的一致性,沒用的註釋及時刪除。

[ 建議3 ] 對於全局數據 (全局變量、常量定義)必須要加註釋。

[ 建議4 ] 一目瞭然的語句可以不加註釋,比如:i++; // i 自增1。

[ 建議5 ] 註釋的位置應與被描述的代碼相鄰,可以與語句同一行,不放在下方。

[ 建議6 ] 當代碼比較長,特別是有多重其那套時,應當在一些段落的結束處加註釋。

[ 建議7 ] 註釋的縮進要與代碼的縮進一致。

[ 建議8 ] 註釋代碼應當註重,“ 為何做 ” ,而不是 “ 怎麼做 ”。

[ 建議9 ] 數值的單位一定要給上註釋。

[ 建議10 ] 復雜的函數中,在分支語句、循環語句結束之後需要適當的註釋,方便區分各個分支或循環體。

2、接續符和轉移符

2.1 續行功能

C語言裡用反斜杠( \ )表示斷航。編譯器會將反斜杠剔除掉,跟在反斜杠後面的字符自動續接到前一行。但是註意:反斜杠之後不能有空格,感興趣的小夥伴可以下來測試下:

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
    if (1 == a && \
        2 == b && \
        3 == c)
    {
        printf("You can see me!\n");
    }
    else
    {
        printf("You can not see me!\n");
    }
    return 0;
}

可能有的小夥伴會好奇,明明我不用 \ 也可以換行不會報錯啊,那為什麼還要用 \ 表示換行呢?我們作為一個程序員,別人可能也會去閱讀我們的代碼,如果不帶 \ 直接換行可能會出現奇異,在一個也可以告訴編譯器這個地方是續行,語義更強!

2.2 轉義字符

C語言中,有一些字符,就是他的字面意思,比如 'n','b','t'。 也有一些字符,本身就是特殊含義的,比如:" , ', \ 轉義的本質含義是:字面轉特殊,或者特殊轉字面。

\ 有兩種用途:

  1. 當續行符使用
  2. 轉義字符使用 (a. 字面轉特殊 b. 特殊轉字面)

這裡我們重點講一下 \n 和 \r可能小夥伴們都聽過換行和回車吧!那麼他們本質上的意思是不一樣的!但是現在很多編譯器讓換行( \n )裡面也包含瞭回車( \r ) 的功能!那他們倆究竟有什麼樣的區別呢?

換行:讓光標移動到下一行

回車:光標回到當前行的最開始

這裡小夥伴可以試一下用C語言寫一個簡單的倒計時功能,就能很明顯的區分換行和回車的區別瞭!

這裡我們也可以來看一道筆試題:

//以下程序輸出什麼?
#include <string.h>
#include <stdio.h>
int main()
{
    printf("%d\n", strlen("abcdef"));
    // \62被解析成一個轉義字符
    printf("%d\n", strlen("c:\test\628\test.c"));
    return 0;
}

這裡第一個打印函數,我們如果有瞭解,strlen() 函數是求字符串中 \0 之前的字符個數,所以第一個打印的是 6 , 第二個打印函數,首先是 \t 被解析成一個轉義字符, \62 也被解析成一個轉義字符 (8進制) 所以第二個打印的應該是 14 !

3、單引號和雙引號

3.1 基本概念

對於C語言有瞭解的小夥伴都知道,單引號引起來的都是字符常量,雙引號引起來的都是字符串常量,但其實對於初學者來說還是容易出錯,比如 'a',和 "a" 是完全不一樣的概念,在字符串中,以 \0 為結尾,他本質上不屬於字符串的元素內容,隻能說他是字符串結束標識符,但是它會占用空間!也就是 'a' 會占一個字節而 "a",則會占兩個字節。

有瞭上面簡單的概念我們來看一個例子:

這裡可能就有小夥伴有疑問瞭,前兩個和最後一個 printf打印結果我還能理解,可是第三個為啥是占四個字節呢?這明明不是一個字符常量嗎?(C++ 中第三個大小為 1 個字節,因為這裡是講C語言所以我們不討論其他語言)

其實在 C99 標準的規定,'1' 叫做整型字符常量(integer character constant),被看成是 int 類型。

光是用 “ 標準規定 ” 用來證明是不可行的,我們再用一個實例來證明:

看到這個結果不要驚訝,我剛剛說過,標準規定,整型字符常量被看成是 int 類型,所以他會有四個字節的空間,而且我當前電腦是小端存儲,所以低字節序放在低地址處,在者,將一個4字節的數據放入 char 類型的變量中是會發生數據截斷的,會將低地址的一個字節內容放入 char 類型的變量中,所以其實最終 c 變量裡放的隻是一個 'd' 字符!

但是我不推薦上面這種寫法!!!我們明白其中道理就好。

那這裡有的小夥伴又開始下去實驗瞭,於是寫出瞭這樣的代碼:

因為一個整型字符常量隻有 4 個字節空間,他如何能放得下 5個字節甚至更多呢?

3.2 特殊情況

顯而易見,是不能出現空整型字符常量的,但是可以出現空字符串,因為字符串結束標識符 \0 雖然不能算字符串元素內容,但是它也是占大小的。

4、邏輯操作符

4.1 && (邏輯與)

概念:級聯兩個(多個)邏輯表達式,必須同時為真,結果才為真。

例子:

對於邏輯與的短路現象,因為我們編譯器是從左往右掃描的,所以如果當表達式左邊為假的話,它就不會去執行邏輯與右邊的表達式,這也就是我們所稱的短路現象:

4.2 || (邏輯或)

概念:級聯兩個(多個)邏輯表達式,必須至少一個為真,結果才為真。

例子:

上面這個例子同時也包含瞭邏輯或的短路現象,在邏輯或中,因為編譯器是從左往右掃描代碼的,所以隻要表達式左邊為真,則不需要進行右邊的判斷。

4.3 邏輯與和邏輯或的筆試題

因為對於前置++和後置++我還沒有講,所以有基礎的同學可以先看看,沒基礎的可以等我下期出瞭符號第二期在回來看這道題。

第一個邏輯與表達式,a 變量的初始值是 0 ,而且是後置++,先使用表達式的值,在進行自增,而邏輯與必須滿足表達式兩邊的值都為真,但凡有一個為假都不會執行後面的表達式,所以隻有 a 變量發生瞭變化。第二個邏輯或表達式,邏輯或隻要表達式兩邊有一個為真即可,a++ 判斷為假,會接著判斷 ++b, 前置++ 是先自增在使用,所以 ++b 表達式為真,也就不會去執行後面表達式瞭,也就是說,隻有 a和b變量的值發生瞭變化。

到此這篇關於C語言各種符號的使用介紹上篇的文章就介紹到這瞭,更多相關C語言符號內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: