C语言 | C语言深度解剖 ——章节2 符号
C語言 | C語言深度解剖 ——章節(jié)2 符號
- C語言基本符號表
- 注釋符號 // /*
- 幾個似非而是的注釋問題
- y=x/*p
- 出色注釋的基本要求
- 連接符和轉義符 \
- 單引號、雙引號
- 花括號
- 運算符 10種
- 1.算數(shù)運算符 7個
- ++、--操作符
- (++i)+(++i)+(++i)
- ++i+++i+++i
- 貪心法
- 2/(-2)的值是多少?
- 2.關系運算符 6個
- 3.邏輯運算符 3個
- 4.位操作運算符 6個
- 左移和右移
- 0x01<<2+3 的值為多少?
- 5.賦值運算符 11個
- 6.條件運算符 ?:
- 7.逗號運算符 ,
- 8.指針運算符 2個
- 9.求字節(jié)數(shù)運算符 sizeof
- 10.特殊運算符 3個
- 運算符的優(yōu)先級
- 運算符的優(yōu)先級表
- 一些容易出錯的優(yōu)先級問題
C語言基本符號表
注釋符號 // /*
幾個似非而是的注釋問題
下面例子那個編譯器會報錯呢?
A) int/…/i;
B)char* s=“abcdefgh //hijklmn”;
C) //Is it a
valid comment?
D) in/…/t i;
答案是只有最后一條不正確,原因如下
A)如果編譯器是剔除注釋部分,那 inti 會報錯,但是編譯器不是簡單地剔除而是替換為空格,所以是 int i;即正確 如下面也是正確的
B)雙引號是字符串常量,雙斜杠也不例外,/*也一樣,只要在雙引號內(nèi)都算字符串
C)\是一個連續(xù)符,所以正確這段注釋 包含下面這一行
D)由于是替換成空格,當前就為in t i;自然不對了
注:/**/不能嵌套/ * 總是與離它最近的 * /匹配
y=x/*p
這段主要想表示 x除以p指向的內(nèi)存的值,把結果賦給y?但編譯出錯,因為編譯器會直接把/*當做注釋的開始,那么修改如下
y = x/ p 或者 y = x/( p)
所以只要斜杠要斜杠和星號之間沒有空格,都會被當作注釋的開始。
出色注釋的基本要求
例如:i++; /* i 加 1 */
多余的注釋
連接符和轉義符 \
C語言中以反斜杠(\)表示斷行。編譯器會剔除反斜杠
注:反斜杠之后不能有空格,下一行之前也不能有空格
如下例子均是合法的
反斜杠除了用作連接符、轉義字符
常用的轉義字符和含義如下
| \n | 回車換行 |
| \t | 橫向跳到下一制表位置 |
| \v | 豎向跳格 |
| \b | 退格 |
| \r | 回車 |
| \f | 走紙換頁 |
| \ | 反斜杠符“\” |
| ’ | 單引號符 |
| \a | 響鈴 |
| \ddd | 1~3位八進制數(shù)所代表的字符 |
| \xhh | 1~2位十六進制所代表的字符 |
| C語言字符集中的任何一個字符均可用轉義字符來表示,表中的\ddd和\xhh正是為此提出的。ddd和hh分別為八進制和十六進制的ASCII代碼,如\102表示字母“B”,\134表示斜線,\X0A表示換行等 |
單引號、雙引號
雙引號""常用來引起來字符串常量,且占用2byte
單引號’‘用來引起來的是字符常量,占用1byte
如下舉例
1,‘1’,“1”
第一個為整形常數(shù),32位系統(tǒng)下占4 byte
第二個為字符常量,占1個byte
第三個是字符串常量,占2個byte
而字符在內(nèi)存里是以ASCAII碼存儲的,所以字符串常量可以與整形常量活變量進行運算,如’A’+1
花括號
花括號即用來打包,如if、while、for、switch等語句都在用它,將一段語句活代碼打包起來,形成一個整體,那么如下例子有什么區(qū)別呢?是否可行呢?
char a[10] = {“abcde”};
char a[10] { = “”};
可以看到第二個是不行的,因為大括號包含的表達式不正確,而如果是以下則是正確的
char b[10]; if(0){“abcde”;}
由于第一個{“abcde”}表述的是char 數(shù)組中一個成員內(nèi)容,而第二個則是一個正確的表達式
注:如上char a[10] = {“abcd”};是一個字符長度為10字符串表達式,不能單獨修改數(shù)組內(nèi)容
即a[i]是無法取到的,而只能直接打印a變量,如下使用
而只有char a[10] = {‘a(chǎn)’,‘b’} 才可以取數(shù)組內(nèi)容 如a[0] = a
而當char a[10] = {“abc”,“cde”};則會拋出初始值定項太多,即此時字符串的話只能有一個
而char a[] 和 char *b使用情況類似,但大小不同,具體如下圖,而char *b的大小是指針大小,所以永遠為4,不隨字符串長度決定,具體待第四章數(shù)組與指針再繼續(xù)學習
char a[10] = {“abc”};
char *b = “efg”;
運算符 10種
1.算數(shù)運算符 7個
用于各類數(shù)值運算。包括加(+)、減(-)、乘(*)、除(/)、求余(或稱模運算,%)、自增(++)、自減(–)共七種。
++、–操作符
++、–作為前綴時,是先做自加、自減,然后再做別的運算,但作為后綴時,什么時候自加自減呢?例子如下:
i=3
A) j= (i++,i++,i++); //i=6,j=5
B) k = (i++) + (i++) + (i++); .//i=6,k=9
C) for (i=0;i<10;i++){…} //i = 10 與++i結果同樣
計算結果已如上,而原因是
A)逗號表達式,i在遇到每一個逗號后,認為本次運算已經(jīng)結束,i這時候自加。
比如
int x;
int i = 3;
x = (++i,i++,i+10);
此時i = 5;x=15 ,即i在遇到每一個逗號后,都認為本次計算結束這是后i才會自加
B)i遇到分號才認為本計算單位結束,此時i再自加,且加入括號,則會先計算括號內(nèi),在計算等號
C)例子i與10進行比較后,在自加,此時i=10
而書中的例子 打印如下,但此時循環(huán)會持續(xù),不會停在10
再來看兩個個例子
(++i)+(++i)+(++i)
int i = 3;
(++i)+(++i)+(++i)
如上表達式最后內(nèi)容結果i為多少呢,4+5+6 = 15?
可以看到結果是18,因為i經(jīng)過3次自加后已經(jīng)變?yōu)? 而三次 則是 6+6+6=18
那當我們?nèi)コㄌ柡竽?#xff1f;
++i+++i+++i
可以看到此時編譯器是報錯的,其實是因為不知道i++還是++i
而只有加入空格,才能正常計算,且結果如上
p = ++i+ ++i+ ++i;
而a++b則是 a++ b ,結果如下
即a+b后賦值給p,再對a++
貪心法
編譯器從左到右一個一個字符的讀入,如果該字符可能組成一個符號,那么再讀入下一個字符,判斷已經(jīng)讀入的兩個字符組成的字符串是否可能是一個符號的組成部分;如果可能,繼續(xù)讀入下一個字符,重復上述判斷,直到讀入的字符組成的字符串已不再可能組成一個有意義的符號。這種處理的策略被稱為“貪心法”。
而需要注意的是:除了字符串與字符常量,符號中間不能嵌有空白(空格、制表符、換行符等)。
比如 ==是單個符號,而= =是兩個等號 ,那么根據(jù)這個就能判斷出a++b表達式與a++ +b一致, 而a+++++b的表達式呢?
仍然是錯誤表達式
2/(-2)的值是多少?
2/(-2)的值為多少?2%(-2)的值呢? ,答案為-1 和0
先看下規(guī)則,假如a除以b,商為q,余數(shù)為r
那么
q = a/b
r = a%b
這里不妨假設b大于0,那么a、b、q、r之間是為什么關系呢?
這三條性質(zhì),是我們認為整數(shù)除法和余數(shù)應該具備的,但是,很不幸它們很可能不同時成立
先考慮一個簡單的例子:3/2 商為1 余數(shù)唯一,那么第一條性質(zhì)滿足,在改一下(-3)/2值呢?答案如果是-1,那么余數(shù)必定是-1,這樣第三條興致無法滿足,如果首先滿足第三條性質(zhì),即余數(shù)為1,這樣根據(jù)第一條性質(zhì)商應該為-2,那么第二條又無法滿足
因此上述矛盾無法解決,所以此時必須放棄上述中的一跳,所以大多數(shù)編譯器會放棄第三條,而改為要求余數(shù)與被除數(shù)的正負號相同
但是,C語言的定義只保證了性質(zhì)1,以及當a>=0且b>0時,保證|r|<|b|以及r>=0,后面部分的保證與性質(zhì)2或性質(zhì)3 比起來,限制性要弱很多
所以如上解釋2/(-2)的值-1,2%(-2)的值為0就能解釋的通了,即商保證符號相同,余數(shù)必須大于等于0
2.關系運算符 6個
用于比較運算。包括大于(>)、小于(<)、等于(==)、 大于等于(>=)、小于等于(<=)和不等于(!=)六種。
3.邏輯運算符 3個
用于邏輯運算。包括與(&&)、或(||)、非(!)三種。
先看如下例子
結果為 i=1 j=0
我們都知道 || 或是只有一個為真,結果為真,而兩個都為假,結果才為假,所以在如上結果中,后面++j>0不會被計算,所以j仍然為0,如果第一個為假,才會去判斷第二個
而&& 則是兩個均要判斷,且只有兩個均為真才能進入,一個為假則不能進入
4.位操作運算符 6個
參與運算的量,按二進制位進行運算。包括位與(&)、位或(|)、位非(~)、位異或(^)、左移(<<)、右移(>>)六種。
其中按位異或操作可以實現(xiàn)不用第三個臨時變量交換兩個變量的值:
左移和右移
左移運算符"<<“是雙目運算符,其功能是把”<<"左邊的運算數(shù)各二進位全部左移若干位,相當于乘法,即<< 1相當于*2 ,<<2則乘4, <<3則乘8 以此類推
右移運算符“>>”,則是吧左邊的運算數(shù)個二進制全部右移若干位,相當于除法
需要注意的是:對于有符號數(shù),在右移時,符號位將隨同移動
單目就是一個操作數(shù),比如++,a++,操作數(shù)只有一個a
雙目就是兩個操作數(shù),最熟悉的就是+,a+b,計算a、b的和
三目就是三個操作數(shù),?:運算符,比如a?b:c,當a的值為真時,結果是b,否則結果是c。
0x01<<2+3 的值為多少?
你以為的是什么?是不是 1* 4 +3 =7 ?但實際結果卻是32,因為"+"號運算符優(yōu)先級是比移位運算符的優(yōu)先級高,所以其實是 1 * 2^5 =32
那么0x01<<2+32 或0x01 <<2-3呢?
顯然都不行,第一個報錯warning: left shift count >= width of type [-Wshift-count-overflow],即已經(jīng)超出范圍
而第二個報錯是warning: left shift count is negative [-Wshift-count-negative],即是消極數(shù),所以左移右移的位數(shù)不能大于數(shù)據(jù)長度,不能小于0
5.賦值運算符 11個
用于賦值運算,分為簡單賦值(=)、復合算術賦值(+=,-=,*=,/=,%=)和復合位運算賦值(&=,|=,^=,>>=,<<=)三類共十一種。
6.條件運算符 ?:
這是一個三目運算符,用于條件求值(? : )。簡化了if-else的操作
表達式1 ? 表達式2 : 表達式3 ,即如果表達式1為幀則選擇表達式2為真?zhèn)€條件的值,否則則選擇表達式3
7.逗號運算符 ,
用于把若干表達式組合成一個表達式(,)。
常用于for結構的括號內(nèi)的第一個表達式
8.指針運算符 2個
用于取內(nèi)容(*)和取地址(&)二種運算。
&var 讀作"var 的地址"
取內(nèi)容、間接尋址運算符,返回操作數(shù)指定地址的變量值
結果如下
val=3000 ptr=296011440 val=30009.求字節(jié)數(shù)運算符 sizeof
用于計算數(shù)據(jù)類型所占的字節(jié)數(shù)(sizeof)。,再說第一章已經(jīng)說了具體sizeof相關用法
10.特殊運算符 3個
有括號(),下標[],成員(→,.)
->成員選擇(指針) . 成員選擇(對象c)
運算符的優(yōu)先級
同一優(yōu)先級的運算符,運算次序由結合方向所決定。
簡單記就是:初級運算符( )、[ ]、->、.
高于 單目運算符
高于 算數(shù)運算符(先乘除后加減)
高于 關系運算符
高于 邏輯運算符(不包括!)
高于 條件運算符
高于 賦值運算符
高于 逗號運算符。
運算符的優(yōu)先級表
一些容易出錯的優(yōu)先級問題
| .的優(yōu)先級高于* ->操作符用于消除這個問題 | *p.f | p所指對象的字段f (*p).f | 先對p取f對象,作為指針,然后進行解除引用操作。*(p.f) |
| []高于* | int *ap[] | ap是個指向int 數(shù)組的指針,int (*ap)[] | ap是個元素為int 指針的數(shù)組 int * (ap[]) |
| 函數(shù)()高于* | int *fp() | fp是個函數(shù)指針,所指函數(shù)返回int。int (*fp)() | fp是個函數(shù),返回int指針 int * int * (fp()) |
| == 和 !=高于位操作 | (val & mask !=0) | (val & mask) != 0 | val & (mask!=0) |
| == 和 !=高于賦值符 | c = getchar() != EOF | (c = getchar() )!=EFO) | c =( getchar() != EOF) |
| 算術運算符高于位移運算符 | msb << 3+1 | (msb << 3)+1 | msb <<(3+1) |
| 逗號運算符在所有運算符中優(yōu)先級最低 | i=1,2 | i = (1,2) | (i =1),2 |
總結
以上是生活随笔為你收集整理的C语言 | C语言深度解剖 ——章节2 符号的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里系App抓包详细分析
- 下一篇: 淘宝直播间商品列表