目錄

零. 前言
一. 算術(shù)操作符
1. 加法 +
2. 減法 -
3. 乘法 *
4. 除法 /
5. 取模 %
總結(jié)
二. 移位操作符
1. 左移操作符<<
2. 右移操作符 >>
總結(jié)
三. 位操作符
1. 按位與 &
2. 按位或 |
3. 按位異或 ^
四. 賦值操作符 =
五. 單目操作符
1. 邏輯反操作符 !
2. 負(fù)值操作符 -
3. 正值操作符 +
3. 取地址操作符 &
4. 解引用操作符 *
5. 類型長(zhǎng)度操作符 sizeof
6. 按位取反操作符 ~
7. 前置/后置 ++ --
8. 強(qiáng)制類型轉(zhuǎn)換 (數(shù)據(jù)類型)
六. 關(guān)系操作符
七. 邏輯操作符
1. 邏輯與 &&
2. 邏輯或 ||
八. 逗號(hào)表達(dá)式
九. 下標(biāo)引用, 函數(shù)調(diào)用及成員訪問(wèn)符
1. 下標(biāo)引用操作符? [ ]
2. 函數(shù)調(diào)用操作符 ( )
3. 結(jié)構(gòu)體成員訪問(wèn)操作符 . ->
十. 三目操作符(條件操作符)
C語(yǔ)言中有很多數(shù)據(jù)類型, 通過(guò)這些數(shù)據(jù)類型可以像日常生活中那樣存儲(chǔ)數(shù)據(jù)了. 日常生活中除了要存儲(chǔ)數(shù)據(jù), 還需要對(duì)數(shù)據(jù)進(jìn)行計(jì)算, 就像去超市購(gòu)買(mǎi)商品進(jìn)行價(jià)格的計(jì)算, 通過(guò)今天是星期幾來(lái)判斷還有幾天到周末. 離春節(jié)還有幾個(gè)星期, 幾個(gè)月等等...... 當(dāng)然C語(yǔ)言中也可以對(duì)數(shù)據(jù)進(jìn)行計(jì)算, 這就必須先了解C語(yǔ)言所包含的種種操作符.

在C語(yǔ)言中, 按照操作數(shù)的個(gè)數(shù)可以分為三種, 單目操作符, 雙目操作符和三目操作符. 單目操作符的意思就是這個(gè)操作符只有一個(gè)操作數(shù), 雙目操作符有兩個(gè)操作數(shù), 三目操作符有三個(gè)操作數(shù).
還可以通過(guò)操作符運(yùn)算的邏輯分為以下這10種, 接下來(lái)我會(huì)詳細(xì)介紹他們的用法和注意事項(xiàng).

加法: +
減法: -
乘法: *
除法: /
取模/取余: %在我們?nèi)粘I钪? 最常見(jiàn)的運(yùn)算就是加減乘除四則運(yùn)算符, 可能對(duì)于 取模/取余% 操作符比較陌生, 沒(méi)關(guān)系, 下文我會(huì)詳細(xì)講解.
1. 加法 +加法+很容易理解, 就是兩個(gè)數(shù)相加, 在C語(yǔ)言中可以進(jìn)行加法運(yùn)算:
int a = 10;
a + 10;
printf("a = %d\n", a);
// 結(jié)果:a = 10變量a的結(jié)果為什么是10呢, 明明已經(jīng)對(duì)變量a進(jìn)行了加法操作. 那是因?yàn)樵贑語(yǔ)言中, a+10 這個(gè)表達(dá)式的值確實(shí)是20, 但是這個(gè)表達(dá)式的值并沒(méi)有通過(guò) 賦值操作符= 賦給變量a, 所以 變量a 的值還是10.
如果需要將a的值更改為20, 上文說(shuō)過(guò)需要使用 賦值操作符= 將表達(dá)式 a+10 的值賦給 變量a, 或者使用 賦值操作符= 直接將 變量a 更改為 20即可. 賦值操作符= 在下文也有詳細(xì)的講解.
// 需求:將a的值更改為20
int a = 10;
a = a + 10;
printf("a = %d\n", a);
// 結(jié)果: a = 20詳細(xì)解剖

其實(shí)加減乘除四則運(yùn)算的使用方法都是一樣的, 本文中就不再過(guò)多的贅述了(`?′)
int a = 10;
int b = 20;
int ret = b - a;
printf("ret = %d\n", ret);
// 結(jié)果:ret = 10
ret = a - b;
printf("ret = %d\n", ret);
// 結(jié)果:ret = -10
int a = 0;
int b = 2;
int c = 3;
printf("%d\n", a * a); // 結(jié)果:0
printf("%d\n", a * b); // 結(jié)果:0
printf("%d\n", b * c); // 結(jié)果:6和數(shù)學(xué)乘法運(yùn)算一樣, 零乘以任何數(shù)的結(jié)果都為零.
4. 除法 /int a = 5;
int b = 2;
int ret = a / b;
printf("ret = %d\n", ret);
// 結(jié)果:ret = 2按照數(shù)學(xué)邏輯來(lái)講, 5除上2的值不應(yīng)該是2.5嗎? 那是因?yàn)樵贑語(yǔ)言中, 如果 除法/ 操作符左右兩個(gè)操作數(shù)的類型都是整型進(jìn)行的就是整數(shù)除法, 整數(shù)除法會(huì)舍棄小數(shù)位, 而且不會(huì)進(jìn)行四舍五入, 計(jì)算的結(jié)果永遠(yuǎn)是整數(shù).
那我將輸出格式符更改為%f以浮點(diǎn)類型輸出總可以了吧 ☆▽☆
int a = 5;
int b = 2;
int ret = a / b;
printf("ret = %f\n", ret);
// 結(jié)果:ret = 0.000000結(jié)果輸出了0.000000, 所以當(dāng)然不行啦, 因?yàn)檎麛?shù)和小數(shù)在計(jì)算機(jī)內(nèi)存中存儲(chǔ)方式都不同, 整數(shù)除法的結(jié)果為整型, 整型以浮點(diǎn)型格式進(jìn)行輸出肯定是不行的, 編譯器也會(huì)發(fā)出如下警告:
![]()
那我強(qiáng)制類型轉(zhuǎn)換總可以了吧:
int a = 5;
int b = 2;
int ret = a / b;
printf("ret = %f\n", (float)ret);
// 結(jié)果:ret = 2.000000強(qiáng)制類型轉(zhuǎn)換雖然可以, 但是這種方法很粗暴, 而且不建議經(jīng)常使用強(qiáng)制類型轉(zhuǎn)換, 因?yàn)閮蓚€(gè)數(shù)據(jù)的類型本來(lái)就不同, 如果進(jìn)行強(qiáng)制類型轉(zhuǎn)換的話, 可能會(huì)發(fā)生精度的丟失. 雖然現(xiàn)在并沒(méi)有感覺(jué)到精度的丟失. 當(dāng)進(jìn)行更加復(fù)雜的計(jì)算時(shí), 自然會(huì)發(fā)生, 所以應(yīng)該少量的使用強(qiáng)制類型轉(zhuǎn)換, 養(yǎng)成良好的編程習(xí)慣.
這里有一個(gè)簡(jiǎn)單的方法, 就是 除法/ 操作符左右的兩個(gè)操作數(shù)有一個(gè)或兩個(gè)為小數(shù)(浮點(diǎn)型)計(jì)算結(jié)果都是浮點(diǎn)型.
int a = 5;
float b = 2.0f; // 將變量b的類型更改為float類型
float ret = a / b;
printf("ret = %f\n", ret);
// 結(jié)果:ret = 2.500000將其中任意一個(gè)變量類型更改為浮點(diǎn)類型, 還需將存放a/b結(jié)果的 變量ret 類型更改為浮點(diǎn)類型.
這樣, 精度就不會(huì)丟失了, 由于計(jì)算機(jī)存儲(chǔ)數(shù)據(jù)只能由二進(jìn)制來(lái)存儲(chǔ), 所以浮點(diǎn)類型在內(nèi)存中存放會(huì)有很細(xì)微的誤差. 浮點(diǎn)類型是如何在內(nèi)存中存放的我會(huì)在之后的文章中進(jìn)行詳細(xì)的講解, 這里我們主要的目標(biāo)是講解C語(yǔ)言中的操作符, 切勿跑題了.
可以發(fā)現(xiàn), float浮點(diǎn)型變量打印的時(shí)候會(huì)默認(rèn)在小數(shù)點(diǎn)后面打印6個(gè)0, 然而double浮點(diǎn)型變量在打印的時(shí)候小數(shù)點(diǎn)后也是6個(gè)0.
5. 取模 %取模操作符, 表達(dá)式結(jié)果為整數(shù)相除之后的余數(shù), 切記取模操作符的兩個(gè)操作數(shù)必須為整數(shù).
printf("%d\n", 5%2); // 結(jié)果:1
printf("%d\n", 6%2); // 結(jié)果:0
printf("%d\n", -5%2); // 結(jié)果:-1
printf("%d\n", 5%-2); // 結(jié)果:1
printf("%d\n", -5%-2); // 結(jié)果:-1通過(guò)結(jié)果可以發(fā)現(xiàn),?左操作數(shù)的正負(fù)號(hào)影響取模結(jié)果的正負(fù)號(hào).
總結(jié)1. 除了 取模操作符%, 其他操作符都可用于整數(shù)和浮點(diǎn)數(shù);
2. 除法/ 操作符左右操作數(shù)為整數(shù)時(shí), 進(jìn)行的是正數(shù)除法, 計(jì)算結(jié)果為整數(shù), 舍棄小數(shù)位, 不進(jìn)行四舍五入. 左右操作數(shù)有一個(gè)或兩個(gè)時(shí)進(jìn)行的都是小數(shù)除法, 結(jié)果為小數(shù);
3. 由于計(jì)算機(jī)內(nèi)存是通過(guò)二進(jìn)制來(lái)存放數(shù)據(jù)的, 然而在存放浮點(diǎn)數(shù)的時(shí)候, 會(huì)存在一定的精度丟失;
4. 取模操作符% 的兩個(gè)操作數(shù)必須為整數(shù), 且左操作數(shù)的正負(fù)號(hào)影響取模結(jié)果的正負(fù)號(hào).

<< 二進(jìn)制位左移操作符
>>二進(jìn)制位右移操作符在講解移位操作符之前, 先要了解數(shù)據(jù)是如何在內(nèi)存中存儲(chǔ)的. 例如x86(32位)系統(tǒng)舉例吧, 32位操作系統(tǒng)中有32根地址線, 一根地址線所能表示形式為真或假(1/0), 即通電或不用電. 通過(guò)1/0能夠組成2^32種表達(dá)形式.

一個(gè) 整型int 在x86系統(tǒng)中占用4個(gè)字節(jié)的空間, 1個(gè)字節(jié)(Byte)等于8個(gè)比特位(bit), 所以一個(gè)int類型寫(xiě)成一個(gè)由32個(gè)二進(jìn)制位組成的數(shù)列:

這里只是簡(jiǎn)單了解int類型變量是如何在內(nèi)存中存放的. 既然了解了一個(gè)數(shù)是如何在內(nèi)存中存放的, 就可以知道 移位操作符其實(shí)就是對(duì)一個(gè)數(shù)的二進(jìn)制位來(lái)進(jìn)行操作, 接下來(lái)就開(kāi)始介紹兩個(gè)移位操作符:
1. 左移操作符<<
語(yǔ)法格式:
int a = 1;
int ret = a<< 1;
printf("ret = %d\n", ret);
結(jié)果:ret = 2移位規(guī)則:
二進(jìn)制位左側(cè)丟棄, 右側(cè)補(bǔ)0
剖析代碼:

左操作數(shù)是負(fù)數(shù)的情況下, 同樣左側(cè)丟棄, 右側(cè)補(bǔ)0. 而且操作數(shù)都不能為小數(shù), 右操作數(shù)不能是負(fù)數(shù).
通過(guò)代碼可以看出來(lái), 其實(shí)左移操作就是對(duì)左操作數(shù)進(jìn)行 乘2 的操作.
2. 右移操作符 >>語(yǔ)法格式:
int a = 4;
int ret = a >>1;
printf("ret = %d\n", ret);
// 結(jié)果:ret = 2通過(guò)代碼可以看出, 右移操作其實(shí)就是對(duì)左操作數(shù)進(jìn)行 除2 的操作.
移位規(guī)則:
首先, 因?yàn)榫幾g器的不同, 移位運(yùn)算共分為兩種:
1. 邏輯右移: 左邊用0填充, 右邊丟棄
2. 算術(shù)右移: 左邊用符號(hào)位填充, 右邊丟棄
如下圖:

現(xiàn)在大多數(shù)編譯器都是算術(shù)右移, 即左邊補(bǔ)符號(hào)位, 右側(cè)丟棄.
總結(jié)1. 移位操作表達(dá)式的左操作數(shù)必須是整數(shù);
2. 右操作數(shù)不能為負(fù)數(shù), 標(biāo)準(zhǔn)中未定義這種寫(xiě)法;
3. 左移運(yùn)算: 左側(cè)丟棄, 右側(cè)補(bǔ)0;
4. 右移運(yùn)算: 右側(cè)丟棄, 左側(cè)補(bǔ)符號(hào)位.

& 按位與
| 按位或
^ 按位異或位操作符也是對(duì)整數(shù)的二進(jìn)制位進(jìn)行操作, 這三個(gè)操作符的操作大邏輯致相同:
1. 按位與 &語(yǔ)法規(guī)定:
對(duì)兩個(gè)操作數(shù)進(jìn)行按位與, 二進(jìn)制相等則為1, 不同為0.
a : 00000000 00000000 00111000 10001010
&
b : 00000000 00000000 10110111 00010111
=
r : 00000000 00000000 00110000 00001010語(yǔ)法格式:
int a = 3;
int b = 2;
int ret = a & b;
printf("ret = %d\n", ret);
// 結(jié)果:ret = 2
// a:00000000 00000000 00000000 00000011 = 3
// b:00000000 00000000 00000000 00000010 = 2
// r:00000000 00000000 00000000 00000010 = 22. 按位或 |語(yǔ)法規(guī)定
對(duì)兩個(gè)操作數(shù)進(jìn)行 按位或 運(yùn)算, 二進(jìn)制位有一個(gè)1則為1, 都是0則為0.
a : 00000000 00000000 00111000 10001010
|
b : 00000000 00000000 10110111 00010111
=
r : 00000000 00000000 10111111 10011111語(yǔ)法格式
int a = 3;
int b = 4;
int ret = a | b;
printf("ret = %d\n", ret);
// 結(jié)果:ret = 7;
// a:00000000 00000000 00000000 00000011 = 3
// b:00000000 00000000 00000000 00000100 = 4
// r:00000000 00000000 00000000 00000111 = 73. 按位異或 ^語(yǔ)法規(guī)定
對(duì)兩個(gè)操作數(shù)進(jìn)行 按位異或 運(yùn)算, 二進(jìn)制位相異為1, 相同為0.
a : 00000000 00000000 00111000 10001010
|
b : 00000000 00000000 10110111 00010111
=
r : 00000000 00000000 10001111 11111101語(yǔ)法格式
int a = 31;
int b = 24;
int ret = a ^ b;
printf("ret = %d\n", ret);
// 結(jié)果:ret = 7;
// a:00000000 00000000 00000000 00011111 = 31
// b:00000000 00000000 00000000 00011000 = 24
// r:00000000 00000000 00000000 00000111 = 7
C語(yǔ)言中的 賦值操作符= 和數(shù)學(xué)中的 等于號(hào)= 書(shū)寫(xiě)格式是一樣的, 但是C語(yǔ)言和數(shù)學(xué)中的含義卻完全不同, 在數(shù)學(xué)中表達(dá)的可能是表示兩個(gè)數(shù)相等, 而C語(yǔ)言中是將一個(gè)值賦給一個(gè)變量. 正因如此, 在日常編程中, 會(huì)犯這種小錯(cuò)誤. 例如本來(lái)是比較兩個(gè)值的是否相等, 符號(hào)卻寫(xiě)成了 單等于號(hào)=, 這樣表達(dá)式的結(jié)果就變成了賦值的值.
語(yǔ)法格式
int num = 10; // 這里的等號(hào)是給num變量初始化(賦初值)
num = 20; // 這里的等號(hào)是更改num的值, 用常量20覆蓋原來(lái)的10
num = 10 + 20; // 右值也可以是表達(dá)式賦值操作符也可以連續(xù)使用
int a = 10;
int b, c, d, e; // 連續(xù)定義整型int變量
a = b = c = d = e = 9; // 連續(xù)賦值但是這種的代碼風(fēng)格不清晰, 這是一種不良的編程習(xí)慣, 不推薦使用. 如下代碼就是比較好的代碼風(fēng)格, 這樣的代碼比較清晰, 一眼能看出每個(gè)變量的值是多少.
int a = 10;
int b = 9;
int c = 9;
int d = 9;
int e = 9;有時(shí)候我們需要對(duì)當(dāng)前變量進(jìn)行運(yùn)算:
int a = 10;
a = a + 10;
printf("%d\n", a);語(yǔ)句2 是將 表達(dá)式 a+10 的值賦給a, 也就是給a加上一個(gè)10, 但是C語(yǔ)言有一個(gè)更加方便易懂的操作符, 就是復(fù)合賦值符:
+=
-=
*=
/=
%=
>>=<<=
&=
|=
^=根據(jù)上面羅列的符合操作符, 我們可以將語(yǔ)句2寫(xiě)成如下樣式
int a = 10;
a += 10; // 拆分: a = a + 10其他的復(fù)合賦值符用法和上方一樣, 這樣去編寫(xiě), 能夠讓代碼看起來(lái)更加清晰, 易懂.

! ????? 邏輯反操作符
- ????? 負(fù)值操作符
+ ????? 正值操作符
& ????? 取地址操作符
sizeof ? ?操作數(shù)的類型長(zhǎng)度(單位:Byte)
~ ????? 對(duì)一個(gè)數(shù)的二進(jìn)制按位取反
-- ???? ? 前置/后置--
++ ???? ? 前置/后置++
* ??? ?? 解引用操作符
(數(shù)據(jù)類型) ??強(qiáng)制類型轉(zhuǎn)換1. 邏輯反操作符 !在我們編寫(xiě)代碼的時(shí)候, 經(jīng)常會(huì)使用到判斷和循環(huán)語(yǔ)句, 在C語(yǔ)言中0表示假, 非0表示真, 而這里的邏輯反操作符的作用就是將假轉(zhuǎn)換為真, 真轉(zhuǎn)換為假.
語(yǔ)法格式
int score = 0;
if (!score)
{
printf("分?jǐn)?shù)為0, 該挨打了!\n");
}這條語(yǔ)句的意思就是, 如果你考了0分你就該挨打了, 但是在C語(yǔ)言中, 0代表的是假, 然而并不會(huì)執(zhí)行if語(yǔ)句中的語(yǔ)句, 但是我們使用了邏輯反操作符, 將這個(gè)表達(dá)式的值轉(zhuǎn)變成了真(默認(rèn)1).
2. 負(fù)值操作符 -注意, 這里的負(fù)號(hào)和雙目操作符的負(fù)號(hào)不一樣, 這個(gè)是單目操作符-, 雖然它們長(zhǎng)得一樣, 但是用途卻完全不一樣, 這里的-號(hào)是代表這個(gè)數(shù)為負(fù)數(shù), 也可以將一個(gè)數(shù)變?yōu)樨?fù)數(shù):
int a = 10;
a = -a;
printf("a = %d\n", a);
// 結(jié)果: -10-a表達(dá)式的結(jié)果為-10, 并沒(méi)有真的將a的值更改為-10, 需要通過(guò)賦值操作符= 將-a表達(dá)式的值賦值給變量a, 這樣a變量的值就變成了-10.
3. 正值操作符 +正值操作符在代碼編寫(xiě)的過(guò)程中基本上不會(huì)使用到, 因?yàn)椴荒軐⒁粋€(gè)負(fù)數(shù)更改為整數(shù), 和數(shù)學(xué)中一樣.
int a = -10;
a = +a;
printf("a = %d\n", a);
// 結(jié)果: -10這樣是行不通的, 單目操作符的+號(hào)只能表示一個(gè)數(shù)為正數(shù)
int a = +10;但是這樣編寫(xiě)代碼就大可不必了, 因?yàn)椴粚?xiě)這個(gè)正號(hào)編譯器默認(rèn)也會(huì)把這個(gè)常量值識(shí)別為正數(shù), 或者本就隱藏了這個(gè)正號(hào)+.
3. 取地址操作符 &在C語(yǔ)言中, 創(chuàng)建一個(gè)變量首先需要在內(nèi)存中開(kāi)辟一塊內(nèi)存空間, 然后使用取地址操作符就可以將該變量的地址取出來(lái), 這個(gè)表達(dá)式的結(jié)果就是該變量的地址, 所以可以通過(guò)printf( )函數(shù)來(lái)打印一個(gè)變量的地址
int num = 10;
printf("num = %p\n", &num); // %p是打印地址的格式化字符
// 打印出來(lái)的是十六進(jìn)制數(shù)如果可以將num變量的地址打印出來(lái), 那能不能將num變量的地址存儲(chǔ)起來(lái)呢? 當(dāng)然是可以的. 一個(gè)整數(shù)需要存儲(chǔ)的話, 需要整型變量來(lái)存儲(chǔ), 那整型變量的地址需要什么來(lái)存儲(chǔ)呢? 需要使用指針變量, 也就是整型指針變量.
語(yǔ)法格式
int num = 10;
int* p_num = #*p_num中的這個(gè)*號(hào)代表 p_num 是一個(gè)指針變量,
而int代表p_num指針變量所指向的類型為int類型
然后通過(guò)取地址操作符將num的地址取出來(lái)再賦給整型指針變量p_num
既然存儲(chǔ)了num變量的地址, 那么這個(gè)指針變量該如何使用呢? 接下來(lái)我會(huì)講解解引用操作符, &和* 這兩個(gè)操作符之間是緊密相關(guān)的.
4. 解引用操作符 *雙目操作符*的作用是將兩個(gè)數(shù)相乘, 然而在單目操作符中, 指針變量可以通過(guò)*號(hào)訪問(wèn)到地址所指向的那塊內(nèi)存地址(也就是這塊地址所存儲(chǔ)的內(nèi)容)
語(yǔ)法格式
int num = 10;
int* p_num = #
*p_num = 20;
printf("num = %d\n", num);
// 結(jié)果: 20
printf("*p_num = %d\n", *p_num);
// 結(jié)果: 20可以發(fā)現(xiàn), num變量本來(lái)存儲(chǔ)的是10, 然后p_num指針變量通過(guò)地址解引用將這塊地址所存儲(chǔ)的數(shù)值更改為了20, 所以打印變量num也是20. 這就是解引用操作符的用處, 這里只講解引用操作符的用處, 關(guān)于指針更詳細(xì)的內(nèi)容我會(huì)在以后的文章中詳細(xì)講解.
5. 類型長(zhǎng)度操作符 sizeof在剛接觸C語(yǔ)言的使用, 使用sizeof操作符的時(shí), 總會(huì)以為sizeof是一個(gè)函數(shù), 因?yàn)樗鼘?shí)在是太像一個(gè)函數(shù)了, 會(huì)見(jiàn)到這樣寫(xiě)的 sizeof(value), 這也難怪會(huì)有人將sizeof理解為一個(gè)函數(shù), 然而我也不例外. 但是它的操作數(shù)是變量/常量的時(shí)候, 它是可以不用加括號(hào)的, 但是操作數(shù)為類型關(guān)鍵字的時(shí)候, 就必須要加上括號(hào)了. 所以證明這個(gè)操作符不是一個(gè)函數(shù).
這個(gè)操作符的用處就是計(jì)算出類型, 變量, 值所在內(nèi)存中所占的內(nèi)存大小, 它在編譯期間就能夠計(jì)算出表達(dá)式的值.
// 基本數(shù)據(jù)類型
printf("%u\n", sizeof(short)); // 結(jié)果:2
printf("%u\n", sizeof(int)); // 結(jié)果: 4
printf("%u\n", sizeof(long)); // 結(jié)果: 4
printf("%u\n", sizeof(long long)); // 結(jié)果: 8
printf("%u\n", sizeof(float)); // 結(jié)果: 4
printf("%u\n", sizeof(double)); // 結(jié)果: 8
// 指針類型
printf("%u\n", sizeof(short*)); // 結(jié)果:4
printf("%u\n", sizeof(int*)); // 結(jié)果: 4
printf("%u\n", sizeof(long*)); // 結(jié)果: 4
printf("%u\n", sizeof(long long*)); // 結(jié)果: 4
printf("%u\n", sizeof(float*)); // 結(jié)果: 4
printf("%u\n", sizeof(double*)); // 結(jié)果: 4可以看到, 使用sizeof操作符可以打印變量在內(nèi)存中所站字節(jié), 但是這里的指針類型不論是short還是int都是4個(gè)字節(jié)呢, 那是因?yàn)橹羔樧兞克鎯?chǔ)的只是地址, 而非這個(gè)地址的值, 所以不需要很大的值, 所以就統(tǒng)一將指針變量的值設(shè)置為4個(gè)字節(jié).
還需要注意的就是sizeof表達(dá)式的結(jié)果為無(wú)符號(hào)類型的, 也就是沒(méi)有負(fù)數(shù), 不可能一個(gè)數(shù)存放在內(nèi)存中占用了負(fù)幾的空間吧.
6. 按位取反操作符 ~這個(gè)操作符也是對(duì)一個(gè)數(shù)的二進(jìn)制位進(jìn)行操作的, 對(duì)一個(gè)數(shù)的二進(jìn)制位進(jìn)行按位取反, 1為0, 0為1
語(yǔ)法格式
int a = 10;
a = ~a;
// ~ 00000000 00000000 00000000 00001010
// 11111111 11111111 11111111 111101017. 前置/后置 ++ --這里的前置/后置++和前面的復(fù)合運(yùn)算符有著異曲同工之處, 也是為了語(yǔ)法更加的整潔, 易書(shū)寫(xiě). 例如我們需要對(duì)num變量+1的操作時(shí), 有可能需要這樣寫(xiě):
int num = 10;
num += 1; // 或者 num = num + 1;這樣寫(xiě)也可以, 但是有一種更加簡(jiǎn)單易懂方式, 那就是使用++操作符
int num = 10;
num++; // 剖析: num++ 可以理解為 num = num + 1;但是要注意的是, 這里前置++和后置++是由區(qū)別的, 前置++是先進(jìn)行+1, 然后在使用, 然而后置++是先使用變量的值, 等到這條語(yǔ)句結(jié)束后(分號(hào)結(jié)尾為一個(gè)語(yǔ)句), 這個(gè)變量才+1, 所以在使用的時(shí)候一定要區(qū)別開(kāi)來(lái).
代碼1:
int num = 10;
printf("num = %d\n", num++); // 結(jié)果: num = 10 因?yàn)橄仁褂弥岛?1
printf("num = %d\n", num); // 結(jié)果: num = 11 因?yàn)閚um已經(jīng)通過(guò)++ +1為11
代碼2:
int num = 20;
printf("num = %d\n", ++num); // 結(jié)果: num = 21; 因?yàn)橄?1后使用8. 強(qiáng)制類型轉(zhuǎn)換 (數(shù)據(jù)類型)強(qiáng)制類型轉(zhuǎn)換, 可以將一個(gè)數(shù)的類型強(qiáng)制轉(zhuǎn)換成另一個(gè)類型, 例如下面的代碼, 我們需要將浮點(diǎn)型13.14的值賦值給整型變量num的時(shí)候, 編譯器就會(huì)發(fā)出警告,直接將浮點(diǎn)類型常量賦值給整型變量可能會(huì)發(fā)生數(shù)據(jù)丟失的問(wèn)題.
int num = 3.14;然而就需要使用強(qiáng)制類型轉(zhuǎn)換將3.14這個(gè)浮點(diǎn)型常量強(qiáng)制轉(zhuǎn)換為int類型的常量在再賦值給num整型變量
int num = (int)3.14;這樣, 編譯器就不會(huì)發(fā)出警告了, 這只是介紹了強(qiáng)制類型轉(zhuǎn)化的用法, 在實(shí)際代碼編寫(xiě)的時(shí)候還有其他的用法, 但是不建議使用強(qiáng)制類型轉(zhuǎn)換, 因?yàn)榭倳?huì)發(fā)生數(shù)據(jù)丟失的.

>大于
>= 大于或等于< 小于<= 小于或等于
!= ?不等于
== ?等于這里的關(guān)系操作符和數(shù)學(xué)中語(yǔ)法是一樣的, 但是還有幾點(diǎn)需要注意:
1. C語(yǔ)言中關(guān)系操作符連續(xù)使用和數(shù)學(xué)中要表達(dá)的意思不一樣, 例如數(shù)學(xué)中想要表達(dá)10到100, 可以寫(xiě)成10<= 100, 但是C語(yǔ)言中可不能這樣寫(xiě), 雖然語(yǔ)法支持, 但是表達(dá)的意思會(huì)有出入.
[表示10~100的區(qū)間]
1.數(shù)學(xué):
10<= x<= 100
2.C語(yǔ)言:
x >= 10 && x<= 100如果非要寫(xiě)成數(shù)學(xué)中的關(guān)系表達(dá)式, 可能會(huì)和想要表達(dá)的意思有一定的出入:

所以, 數(shù)學(xué)中的邏輯和C語(yǔ)言還是有一定的出入的, 但是大體上的語(yǔ)法還是一致的, 所以這里想要表達(dá)的意思是如果num大于等于10并且小于等于100就打印字符串"這樣行嗎?", 所以說(shuō)應(yīng)該寫(xiě)成: (10<= num && num<= 100)就可以了.
2. 數(shù)學(xué)中表示相等的是一個(gè)等于號(hào), 而C語(yǔ)言中表示相等是雙等號(hào), 一個(gè)等號(hào)表示賦值操作. 前面已經(jīng)說(shuō)過(guò)了, 現(xiàn)在再說(shuō)一遍;
有時(shí)候我們只是想在if中判斷一下兩個(gè)值是否相等, 總是會(huì)有犯迷糊的時(shí)候嘛, 會(huì)將雙等號(hào)寫(xiě)成一個(gè)等號(hào), 導(dǎo)致程序出現(xiàn)問(wèn)題, 而不好排查, 可以將常量放在操作符的左邊.
int num = 0;
if (num = 0) // error
{
printf("num 等于 0\n");
}
if (0 == num) // √
{
printf("num 等于 0\n");
}這樣, 盡管粗心寫(xiě)成了一個(gè)等號(hào), 語(yǔ)法上都是錯(cuò)誤的, 編譯器會(huì)報(bào)錯(cuò), 因?yàn)椴荒軐⒁粋€(gè)值賦給一個(gè)常量, 這樣就能夠快速的定義到問(wèn)題出現(xiàn)的位置了.

&& 邏輯與(并且)
|| 邏輯或(或者)1. 邏輯與 &&操作符兩邊的表達(dá)式結(jié)果都為真(非0)的話, 那么邏輯與表達(dá)式的結(jié)果為真(1), 如果邏輯與表達(dá)式兩邊的表達(dá)式值有一個(gè)為假(0), 則整個(gè)邏輯與表達(dá)式結(jié)果為假(0).
2. 邏輯或 ||操作符兩邊的表達(dá)式結(jié)果如果有一個(gè)為真(非0), 則整個(gè)邏輯或表達(dá)式的結(jié)果為真(1), 如果都是假(0)則整個(gè)邏輯或表達(dá)式為假(0). 這里的邏輯與&&優(yōu)先級(jí)要比邏輯或||要高
需要注意的是, 這兩個(gè)邏輯操作符會(huì)發(fā)生短路的現(xiàn)象:


語(yǔ)法格式
int a = (1,2,3,4,5,6,7,8,9,10);
printf("a = %d\n", a);
// 結(jié)果: a = 10變量a的值為10, 原因是逗號(hào)表達(dá)式是從左往右依次開(kāi)始執(zhí)行, 一直執(zhí)行到最后一個(gè)值, 表達(dá)式最后一個(gè)值為整個(gè)表達(dá)式的值, 所以a的值為10.
逗號(hào)表達(dá)式中可以填寫(xiě)表達(dá)式和變量等等......

[] 下標(biāo)引用操作符
() 函數(shù)調(diào)用操作符
. 結(jié)構(gòu)體成員訪問(wèn)符
->結(jié)構(gòu)體指針成員訪問(wèn)符1. 下標(biāo)引用操作符? [ ]int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; // 這里的方括號(hào)是規(guī)定int類型的數(shù)組有多少個(gè)元素
arr[9] = 11; // 這里數(shù)組名通過(guò)下標(biāo)引用操作符[]將下表為9元素的值更改為11這里需要注意的是, 這就是一個(gè)雙目操作符, 有兩個(gè)操作數(shù), 數(shù)組名和下標(biāo)值, 這里的arr[9]也可以寫(xiě)成9[arr], 這是為什么呢? 可以理解成 a == 10 也可以寫(xiě)成 10 == a 一樣, 其實(shí)應(yīng)該寫(xiě)成 arr[ ]9 這樣的, 但是語(yǔ)法規(guī)定要將下標(biāo)值或者數(shù)組名寫(xiě)在方括號(hào)中 , 但是不建議寫(xiě)成 9[arr], 雖然語(yǔ)法規(guī)定可以這樣去寫(xiě), 但是并沒(méi)有 arr[9] 這樣寫(xiě)看起來(lái)直觀易懂.
2. 函數(shù)調(diào)用操作符 ( )// 自定義: 兩數(shù)相加(int, int)
int add(int x, int y)
{
return x + y;
}
int main(void)
{
int a = 10;
int b = 20;
printf("%d + %d = %d\n", a, b, add(a, b)); // 對(duì)函數(shù)名add使用()號(hào)來(lái)調(diào)用add函數(shù)
// 結(jié)果:10 + 20 = 30
return 0;
}這里的函數(shù)調(diào)用符號(hào)其實(shí)也和下標(biāo)引用操作符大差不差, 左操作數(shù)為函數(shù)名, 右操作數(shù)為被調(diào)函數(shù)所需要的參數(shù)(需要放在括號(hào)中).
3. 結(jié)構(gòu)體成員訪問(wèn)操作符 . ->語(yǔ)法格式
#include// 學(xué)生結(jié)構(gòu)
struct Student
{
char name[20];
int age;
char tel[20];
};
// 打印結(jié)構(gòu)體成員
void print_Student(struct Student* p_stu)
{
printf("name = %s, age = %d, tel = %s\n", p_stu->name, p_stu->age, p_stu->tel);
//printf("name = %s, age = %d, tel = %s\n", (*p_stu).name, (*p_stu).age, (*p_stu).tel);
}
int main(void)
{
struct Student stu1 = {"小紅", 16, "123456789"};
struct Student stu2 = {"小明", 17, "123456789"};
printf("name = %s, age = %d, tel = %s\n", stu1.name, stu1.age, stu1.tel);
// 運(yùn)行結(jié)果:name = 小紅, age = 16, tel = 123456789
print_Student(&stu2);
// 運(yùn)行結(jié)果:name = 小明, age = 17, tel = 123456789
return 0;
} 結(jié)構(gòu)體變量傳參的時(shí)候, 被調(diào)函數(shù)可以將指針解引用再使用.號(hào)來(lái)訪問(wèn)結(jié)構(gòu)體成員, 要注意的是.號(hào)要比*的優(yōu)先級(jí)要高, 所以需要將*p_stu用括號(hào)括起來(lái)再訪問(wèn)結(jié)構(gòu)體成員.

條件操作符是C語(yǔ)言中唯一一個(gè)三目操作符, 它的語(yǔ)法和if else一樣, 如下代碼所示:
// 求a和b的大值
int a = 10;
int b = 20;
int max = 0;
if(a >b)
{
max = a;
}
else
{
max = b;
}可以發(fā)現(xiàn), 上面的代碼可以求出a和b的大值, 代碼行數(shù)過(guò)于多, 可以使用條件操作符:
int a = 10;
int b = 20;
int max = a >b : a ? b;
// 如果a大于b, 則整個(gè)表達(dá)式的值為問(wèn)號(hào)左邊的a
// 如果a不大于b,則整個(gè)表達(dá)式的值為問(wèn)號(hào)右邊的b這樣的代碼風(fēng)格是比較好的, 而且也比較清晰易懂,? 但是最好不要嵌套使用, 因?yàn)橐坏┣短资褂镁蜁?huì)變得不那么易懂了.

好了, C語(yǔ)言的操作符基本介紹就到此為止了, 當(dāng)然, 我目前的狀態(tài)仍是小白一名, 還有很多地方?jīng)]有講明白甚至講錯(cuò)了, 希望大佬們狠狠的批評(píng)吧, 也希望能夠通過(guò)大佬們的指點(diǎn)和批評(píng)中吸取經(jīng)驗(yàn)并逐漸進(jìn)步.??ヽ(°▽°)ノ?
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)站欄目:C語(yǔ)言操作符詳解-創(chuàng)新互聯(lián)
鏈接地址:http://www.yijiale78.com/article6/djgoig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開(kāi)發(fā)、網(wǎng)站導(dǎo)航、搜索引擎優(yōu)化、品牌網(wǎng)站建設(shè)、網(wǎng)站改版、虛擬主機(jī)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容