“不飛則已,一飛沖天;不鳴則已,一鳴驚人。” 今天,我們一起來學(xué)習(xí)一下操作符的相關(guān)知識(shí)。
1.操作符分類
算術(shù)操作符
+ - * / %
移位操作符<< >>
位操作符& | ^
賦值操作符= += -= *= /=...
單目操作符! sizeof ++ -- ...
關(guān)系操作符> >= < <= == !=
邏輯操作符&& ||
條件操作符? :
逗號(hào)表達(dá)式,
下標(biāo)引用、函數(shù)調(diào)用和結(jié)構(gòu)成員[] () ->
2.算術(shù)操作符
+ - * / %
注:1.除了
%
操作符之外,其他的幾個(gè)操作符都可以作用于整數(shù)和浮點(diǎn)數(shù)。
2.對(duì)于/
操作符,如果兩個(gè)數(shù)操作數(shù)都為整數(shù),執(zhí)行整數(shù)除法。而只要有浮點(diǎn)數(shù),執(zhí)行的就是浮點(diǎn)數(shù)的除法。
3.%
操作符的兩個(gè)操作數(shù)必須為整數(shù),返回的是整除之后的余數(shù)。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int m = 7 / 2;
printf("%d\n", m);
double n = 7.0 / 2;
printf("%lf\n", n);
int o = 7 % 2;
printf("%d\n", o);
return 0;
}
3.移位操作符
>>右移操作符 <<左移操作符
注:移位操作符的操作數(shù)只能是整數(shù)。
對(duì)于一個(gè)整數(shù),是4個(gè)字節(jié) = 32個(gè)比特位。一個(gè)整數(shù)寫成二進(jìn)制序列的時(shí)候,就是32個(gè)比特位。對(duì)于有符號(hào)的整數(shù)來說,最高位為符號(hào)位,符號(hào)位是1表示負(fù)數(shù),符號(hào)位是0表示正數(shù)。
對(duì)于無符號(hào)數(shù)整數(shù)來說,沒有符號(hào)位,所有位都是有效位。
整數(shù)的二進(jìn)制表示形式有3種:原碼、反碼、補(bǔ)碼。
原碼:按照數(shù)值的正負(fù),直接寫出的二進(jìn)制序列就是原碼。
例如:10
這個(gè)數(shù)的原碼
就是00000000000000000000000000001010
,那么-10
的原碼就是10000000000000000000000000001010
。
注:對(duì)于正的整數(shù),原碼、反碼、補(bǔ)碼相同,無需計(jì)算。
對(duì)于負(fù)的整數(shù),原碼、反碼、補(bǔ)碼是需要計(jì)算的。
反碼:原碼的符號(hào)位不變,其他位按位取反。(按位取反,原來是0的改為1,原來是1的改為0)
補(bǔ)碼:反碼的二進(jìn)制+1就得到補(bǔ)碼。
因此,10
這個(gè)數(shù)的原碼、反碼、補(bǔ)碼
都是00000000000000000000000000001010
。-10
的原碼就是10000000000000000000000000001010
,反碼是11111111111111111111111111110101
,補(bǔ)碼是11111111111111111111111111110110
。整數(shù)在內(nèi)存中存儲(chǔ)的都是補(bǔ)碼的二進(jìn)制序列。 整數(shù)在計(jì)算的時(shí)候,使用的也是補(bǔ)碼。
3.1左移位操作符
移位規(guī)則:左邊拋棄,右邊補(bǔ)0
#include <stdio.h>
int main()
{
//m:00000000000000000000000000000111
int m = 7;
int n = m << 1;
//左移位原則:左邊拋棄,右邊補(bǔ)0
//n:00000000000000000000000000001110
//n = 2+4+8=14
printf("%d\n", m);
printf("%d\n", n);
return 0;
}
我們可以發(fā)現(xiàn)左移位操作符可以起到加倍的作用。負(fù)數(shù)也是一樣的道理:
3.2右移操作符
移位規(guī)則(右移運(yùn)算分兩種):
1.邏輯移位:左邊用0填充,右邊丟棄。
2.算術(shù)移位:左邊用原該值的符號(hào)位填充,右邊丟棄。
//右移位操作符
#include <stdio.h>
int main()
{
//a的原碼:10000000000000000000000000001010
//a的反碼:11111111111111111111111111110101
//a的補(bǔ)碼:11111111111111111111111111110110
//大多數(shù)編譯器采用的是算術(shù)右移
//b是算術(shù)右移(右邊直接丟棄,左邊補(bǔ)原符號(hào)位,原來是負(fù)數(shù),左邊補(bǔ)1,原來是正數(shù),左邊補(bǔ)0)
//b的補(bǔ)碼:11111111111111111111111111111011
//b的反碼:11111111111111111111111111111010
//b的原碼:10000000000000000000000000000101
//b=-(1+4)=-5
int a = -10;
int b = a >> 1;
printf("a=%d\n", a);
printf("b=%d\n", b);
return 0;
}
我們可以看到,算術(shù)右移也起到了/2
的作用。
注:對(duì)于移位操作符,不要移動(dòng)負(fù)數(shù)位,這個(gè)是標(biāo)準(zhǔn)未定義的。
4.位操作符
位操作符有:
|(按位或)&(按位與)^(按位異或)
注:他們的操作數(shù)必須是整數(shù)。
4.1按位與&
對(duì)于兩個(gè)數(shù)a和b
,用按位與運(yùn)算符求c = a&b;
,需要先寫出a和b
的二進(jìn)制位的補(bǔ)碼形式,然后一一對(duì)比,只有當(dāng)兩個(gè)數(shù)a和b的對(duì)應(yīng)的補(bǔ)碼都為1的時(shí)候,按位與的結(jié)果才是1,否則為0。
#include <stdio.h>
int main()
{
int a = 3;
int b = -5;
int c = a & b;//按(二進(jìn)制)位與
//-5的原碼:10000000000000000000000000000101
//-5的反碼:10000000000000000000000000000100
//-5的補(bǔ)碼:11111111111111111111111111111011
// 3的補(bǔ)碼: 00000000000000000000000000000011
// 按位與:兩個(gè)都為1才為1
// c: 00000000000000000000000000000011
//結(jié)果為3
printf("%d\n", c);
return 0;
}
4.2按位或|
對(duì)于兩個(gè)數(shù)a和b
,用按位或運(yùn)算符求c = a|b;
,需要先寫出a和b
的二進(jìn)制位的補(bǔ)碼形式,然后一一對(duì)比,只要當(dāng)兩個(gè)數(shù)a和b的對(duì)應(yīng)的補(bǔ)碼有一個(gè)為1的時(shí)候,按位或的結(jié)果就是1,否則為0。
#include <stdio.h>
int main()
{
int a = 3;
int b = -5;
int c = a | b;//按(二進(jìn)制)位或
//-5的原碼:10000000000000000000000000000101
//-5的反碼:10000000000000000000000000000100
//-5的補(bǔ)碼:11111111111111111111111111111011
// 3的補(bǔ)碼: 00000000000000000000000000000011
// 按位或:有一個(gè)為1即為1
// c的補(bǔ)碼: 11111111111111111111111111111011
// c的反碼: 11111111111111111111111111111010
// c的原碼: 10000000000000000000000000000101
//結(jié)果為-5
printf("%d\n", c);
return 0;
}
4.3按位異或^
對(duì)于兩個(gè)數(shù)a和b
,用按位或運(yùn)算符求c = a^b;
,需要先寫出a和b
的二進(jìn)制位的補(bǔ)碼形式,然后一一對(duì)比,兩個(gè)數(shù)a和b的對(duì)應(yīng)的補(bǔ)碼相同為0,不同為1.
#include <stdio.h>
int main()
{
int a = 3;
int b = -5;
int c = a ^ b;//按(二進(jìn)制)位異或
//-5的原碼:10000000000000000000000000000101
//-5的反碼:10000000000000000000000000000100
//-5的補(bǔ)碼:11111111111111111111111111111011
// 3的補(bǔ)碼: 00000000000000000000000000000011
// 按位異或:相同為0不同為1
// c的補(bǔ)碼: 11111111111111111111111111111000
// c的反碼: 11111111111111111111111111110111
// c的原碼: 10000000000000000000000000001000
//結(jié)果為-8
printf("%d\n", c);
return 0;
}
注:特別地,a^a=0; a^0=a;
.
下面,我們給出一個(gè)特別的題:在不創(chuàng)建臨時(shí)變量的情況下(沒有第三個(gè)變量),實(shí)現(xiàn)兩個(gè)數(shù)的交換。
通過前面的學(xué)習(xí),我們知道在使用第三個(gè)變量是怎么實(shí)現(xiàn)的了:
//實(shí)現(xiàn)兩個(gè)數(shù)的交換
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = 0;
printf("交換前a=%d,b=%d\n", a, b);
c = a;
a = b;
b = c;
printf("交換后a=%d,b=%d\n",a,b);
return 0;
}
那么,如果我們不使用第三個(gè)變量,該如何實(shí)現(xiàn)同樣的功能呢?
//實(shí)現(xiàn)兩個(gè)數(shù)的交換
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
printf("交換前a=%d,b=%d\n", a, b);
a = a + b;
b = a - b;
a = a - b;
printf("交換后a=%d,b=%d\n", a, b);
return 0;
}
這里,我們只用了兩個(gè)變量,但是還是存在缺陷,就是當(dāng)a和b
的值很大的時(shí)候,就會(huì)出現(xiàn)溢出的問題。這里,我們就需要用到異或^
這個(gè)操作符了。
//實(shí)現(xiàn)兩個(gè)數(shù)的交換
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
printf("交換前a=%d,b=%d\n", a, b);
a = a ^ b;//a=3^5;
b = a ^ b;//b=3^5^5=3
a = a ^ b;//a=3^5^3=3^3^5=5
//異或支持交換律
printf("交換后a=%d,b=%d\n", a, b);
return 0;
}
注:異或^
不存在溢出的問題,但是可讀性不高,只限于整型的運(yùn)算。
5.賦值操作符
賦值操作符用于在變量創(chuàng)建好之后對(duì)值的修改。
#include <stdio.h>
int main()
{
int a = 3;//不是賦值,是初始化
a = 10;//賦值
return 0;
}
賦值操作符可以連續(xù)使用,比如:
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
int c = a = a + b;//連續(xù)賦值
//連續(xù)賦值從右往左算
//a = a + b = 30
//c = a = 30
printf("%d\n", c);
return 0;
}
但是,連續(xù)賦值的語句不利于調(diào)試,上述的int c = a = a + b;
可以拆分成:
a = a + b;
c = a;
//這樣的寫法更清晰爽朗且易于調(diào)試。
復(fù)合賦值符:
+= -= *= /= %= >>= <<= &= |= ^=
這些運(yùn)算符都可以寫成復(fù)合的效果,例如:
int a = 2;
//以下兩種寫法表達(dá)含義一致
a = a + 10;
a += 10;
6.單目操作符
6.1單目操作符的介紹
單目操作符 | 名稱 |
---|---|
! | 邏輯反操作符 |
- | 負(fù)值 |
+ | 正值 |
& | 取地址 |
sizeof | 操作數(shù)的類型長度(以字節(jié)為單位) |
~ | 對(duì)一個(gè)數(shù)的二進(jìn)制按位取反 |
- - | 前置、后置- - |
++ | 前置、后置++ |
* | 間接訪問操作符(解引用操作符) |
(類型) | 強(qiáng)制類型轉(zhuǎn)換 |
1.邏輯反操作符(!)
//0表示假,1表示真
#include <stdio.h>
int main()
{
int a = 1;
int b = 0;
b = !a;
printf("%d\n", b);
return 0;
}
2.解引用操作符(*)
//解引用操作符*
#include <stdio.h>
int main()
{
int a = 10;
int* p = &a;
*p;//對(duì)p解引用操作,*p是通過p中存放的地址,找到p指向的對(duì)象
//*p就是a
return 0;
}
3.sizeof和數(shù)組
//sizeof計(jì)算的是類型創(chuàng)建變量或變量的大小,單位是字節(jié)
//sizeof計(jì)算的結(jié)果是size_t類型的
//size_t是無符號(hào)的
//對(duì)size_t類型的數(shù)據(jù)進(jìn)行打印,可以用%zd
//sizeof后面的括號(hào)在括號(hào)中寫的不是類型的時(shí)候,括號(hào)可以省略,這樣也說明了sizeof不是函數(shù)
//sizeof是操作符-單目操作符
#include <stdio.h>
int main()
{
int a = 10;
printf("%zd\n", sizeof(a));
printf("%zd\n", sizeof a);
printf("%zd\n", sizeof(int));
int arr[10] = { 0 };
printf("%zd\n", sizeof arr);
printf("%zd\n", sizeof(arr[1]));
return 0;
}
4.~(對(duì)一個(gè)數(shù)的二進(jìn)制按位取反)
#include <stdio.h>
int main()
{
int a = 0;
printf("%d\n", ~a);
//a的補(bǔ)碼: 00000000000000000000000000000000
// 按位取反,就是不論是不是符號(hào)位都取反
//~a的補(bǔ)碼:11111111111111111111111111111111
//~a的反碼:11111111111111111111111111111110
//~a的原碼:10000000000000000000000000000001
// 符號(hào)位0為正 1為負(fù)
//~a的值為-1
return 0;
}
那么,接下來,可以看看~
怎么用?
#include <stdio.h>
int main()
{
int a = 10;
//000000000000000000000000000001010
//如果我們想讓從右往左數(shù)第三個(gè)數(shù)變成1該怎么做?
// 即變成00000000000000000000000000001110為14
//將000000000000000000000000000000001左移二
//1<<2 00000000000000000000000000000100
//將左移后的二進(jìn)制位與a的二進(jìn)制位按位或即可
a |= (1 << 2);
printf("%d\n", a);
//那么,反過來,如果希望從右往左數(shù)第三個(gè)數(shù)再變?yōu)?該怎么辦?
// 只需要將下面第一個(gè)和第二個(gè)按位與就能得到第三個(gè)
//0000000000000000000000000000001110
//1111111111111111111111111111111011,這個(gè)可以將(1<<2)取反得到
//0000000000000000000000000000001010
a &= ~(1 << 2);
printf("%d\n", a);
return 0;
}
5.++ --
操作符
#include <stdio.h>
int main()
{
int a = 2;
//++a;
//++是一種自增1的操作
a++;
//前置++和后置++對(duì)于a本身沒有影響,都是進(jìn)行+1的操作
printf("%d\n", a);
return 0;
}
前置++和后置++對(duì)于a本身沒有影響但是對(duì)于別人有影響!示例如下:
#include <stdio.h>
int main()
{
int a = 2;
int b = a++;
//后置++:先使用,后+1
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
#include <stdio.h>
int main()
{
int a = 2;
int b = ++a;
//前置++:先+1,后使用
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
前置--和后置--和前、后置++同理,大家可以自己試一下!
文章來源:http://www.zghlxwxcb.cn/news/detail-639965.html
好啦,關(guān)于操作符的知識(shí)點(diǎn)就先講到這里,后期會(huì)繼續(xù)更新,歡迎大家持續(xù)關(guān)注、點(diǎn)贊和評(píng)論!文章來源地址http://www.zghlxwxcb.cn/news/detail-639965.html
到了這里,關(guān)于初階C語言-操作符詳解(上)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!