本篇文章,我們將展開講解C語言中的各種常用操作符,幫助大家更容易的解決一些運算類問題。
這里提醒一下小伙伴們,本章知識會大量涉及到二進制序列,不清楚二進制序列的小伙伴,可以去閱讀我的另一篇文章《數(shù)據(jù)在內(nèi)存中的存儲》學(xué)習(xí)了解。
目錄
一.操作符分類
二.操作符講解
1.算數(shù)操作符
2.移位操作符
(1)左移操作符?
(2)右移操作符
3.位操作符
(1)& 按位與
?(2)| 按位或
?(3)^ 按位異或
4.賦值操作符
5.單目操作符
總結(jié)
一.操作符分類
- 算術(shù)操作符
- 移位操作符
- 位操作符
- 賦值操作符
- 單目操作符
- 關(guān)系操作符
- 邏輯操作符
- 條件操作符
- 逗號表達式
- 下標引用,函數(shù)調(diào)用和結(jié)構(gòu)成員
二.操作符講解
由于操作符數(shù)量過多,所以本期文章我們將僅僅講解前五種。
1.算數(shù)操作符
算數(shù)操作符包括?“+,-,*,/,%”?五個。較為簡單,小伙伴們只需要注意以下幾點:
- 除了“%”操作符之外,其他的幾個操作符可以作用于整數(shù)和浮點數(shù)。
- 對于“/”操作符如果兩個操作數(shù)都為整數(shù),執(zhí)行整數(shù)除法。只要有浮點數(shù)就執(zhí)行浮點數(shù)除法。
- “%”操作符的兩個操作數(shù)必須為整數(shù),返回的是整除后的余數(shù)。
2.移位操作符
<<? ? ? ? 左移操作符
>>? ? ? ? 右移操作符
移位操作符的左邊是要操作的數(shù),右邊則是要移動的位數(shù)。
要注意的是,移位操作符的操作數(shù)只能是整數(shù),移動的對象則是整數(shù)的二進制序列。
一個整型占四個字節(jié),也就是32個bit位,要記住,整型在數(shù)據(jù)中存儲的是二進制序列的補碼,所以我們對整型的操作都是對其補碼進行操作的。
(1)左移操作符?
左移操作符,顧名思義就是將整數(shù)的二進制序列向左邊移動唄,那么它的規(guī)則是什么呢???
移位規(guī)則:
左邊丟棄,右邊補0
#include<stdio.h>
int main()
{
int n = 6;
//00000000 00000000 00000000 00000110-移動前
//00000000 00000000 00000000 00001100-移動后
int m = n << 1;
printf("%d\n", n);
printf("%d\n", m);
return 0;
}
如上代碼,將“6”的二進制序列向左移動一位,便得到了一個新的二進制序列。結(jié)果如下:
?由結(jié)果可以看出,移位操作符并不會改變操作數(shù)本身,而且細心的小伙伴們可以看出,向左移動一位不就相當于每一位的數(shù)字都“乘2”嘛,也就是將數(shù)字翻倍,移動n位,便翻2的n次方倍。
負數(shù)的操作與之一樣,就是小伙伴們千萬不要忘記原碼和補碼之間的轉(zhuǎn)換。
(2)右移操作符
移位規(guī)則:
右移運算分為兩種:
1.邏輯移位
左邊用0填充,右邊丟棄
2.算術(shù)移位
左邊用原值的符號位填充,右邊丟棄
不同的編譯器會有不同的右移運算,但是我們平時所使用的絕大多數(shù)編譯器都是算數(shù)右移。
#include<stdio.h>
int main()
{
int n = -15;
//10000000 00000000 00000000 00001111-原碼
//11111111 11111111 11111111 11110000-反碼
//11111111 11111111 11111111 11110001-補碼
//11111111 11111111 11111111 11111000-移動后補碼
//11111111 11111111 11111111 11110111-移動后反碼
//10000000 00000000 00000000 00001000-移動后原碼
int m = n >> 1;
printf("%d\n", n);
printf("%d\n", m);
return 0;
}
結(jié)果如下:?
?同左移類似,右移則是將數(shù)字折半,但是如果是奇數(shù)的話,結(jié)果則會是比小數(shù)小的最臨近于小數(shù)的負數(shù)。比如-15的右移結(jié)果就是-8。
3.位操作符
&? ? ? ?按位與
|? ? ? ? ?按位或
^? ? ? ? 按位異或
位操作符的操作數(shù)也必須是整數(shù),也是對其二進制序列動手。
(1)& 按位與
假如我是一個企業(yè)高管,我現(xiàn)在需要程序員A與程序員B一起來完成某個項目,這說明,A和B是必不可少的,他們兩個少了誰這個項目都完不成。這便是按位與。
口訣:同真則真,有假則假
#include<stdio.h>
int main()
{
int a = 6;
//00000000 00000000 00000000 00000110-補碼
int n = -15;
//11111111 11111111 11111111 11110001-補碼
int m = a & n;
//00000000 00000000 00000000 00000110-補碼
//11111111 11111111 11111111 11110001-補碼
//00000000 00000000 00000000 00000000-m的補碼(重點)
printf("%d\n", m);
return 0;
}
我們習(xí)慣上將二進制序列的“1”視為真,“0”視為假,a&n,便是兩個二進制序列對應(yīng)的每一位相與,從而得到一個新的二進制序列。
由上可知,m的二進制序列全為0,也就代表m的值為0,結(jié)果如下:
?(2)| 按位或
假如我又是一個企業(yè)高管,我現(xiàn)在需要程序員A或程序員B來完成某個項目,這說明,A和B他們兩個只要有一個能來做這個項目,就能成,如果一個都沒有,就做不了。這便是按位或。
口訣:同假則假,有真則真
#include<stdio.h>
int main()
{
int a = 6;
//00000000 00000000 00000000 00000110-補碼
int n = -15;
//11111111 11111111 11111111 11110001-補碼
int m = a | n;
//00000000 00000000 00000000 00000110-補碼
//11111111 11111111 11111111 11110001-補碼
//11111111 11111111 11111111 11110111-m的補碼(要點)
//11111111 11111111 11111111 11110110-m的反碼
//10000000 00000000 00000000 00001001-m的原碼
printf("%d\n", m);
return 0;
}
對兩個二進制序列的每一位相或,便得到m的補碼,但是m的符號位為1,是負數(shù),所以要轉(zhuǎn)化為原碼來讀。
結(jié)果如下:
?(3)^ 按位異或
假如我還是一個企業(yè)高管……這個不好舉例子了哈哈哈直接來看口訣:
相同為0,不同為1
#include<stdio.h>
int main()
{
int a = 6;
//00000000 00000000 00000000 00000110-補碼
int n = -15;
//11111111 11111111 11111111 11110001-補碼
int m = a ^ n;
//00000000 00000000 00000000 00000110-補碼
//11111111 11111111 11111111 11110001-補碼
//11111111 11111111 11111111 11110111-m的補碼(重點)
//11111111 11111111 11111111 11110110-m的反碼
//10000000 00000000 00000000 00001001-m的原碼
printf("%d\n", m);
return 0;
}
將兩個二進制序列的每一位相異或,結(jié)果如下:
4.賦值操作符
所謂賦值操作符,也就是我們經(jīng)常使用的“ = ”,將一個常量或者常量表達式賦給一個變量。
int a = 1;//不是賦值,是創(chuàng)建之后的初始化
a = 5;//是賦值
int b = 2;
int c = 0;
c = a + b;//也是賦值
除了等號以外,還有一些常用的復(fù)合賦值操作符:
+=? ? ? ? -=? ? ? ? *=? ? ? ? /=? ? ? ? %=? ? ? ? >>=? ? ? ? <<=? ? ? ? &=? ? ? ? |=? ? ? ? ^=
這些符合賦值其實是兩個運算式的合并,例如:
int a = 2;
a = a + 5 和 a += 5 是一樣的效果,后者看起來會更加的簡潔
5.單目操作符
所謂單目,也就是這種操作符的操作數(shù)只有一個。
- !? ? ? ? ? ? ? ? 邏輯反操作
- -? ? ? ? ? ? ? ? ? ?負值
- +? ? ? ? ? ? ? ? ? 正值
- &? ? ? ? ? ? ? ? ? 取地址
- sizeof? ? ? ? ? ?操作數(shù)的類型長度(以字節(jié)為單位)
- ~? ? ? ? ? ? ? ? ? 對一個數(shù)的二進制按位取反
- --? ? ? ? ? ? ? ? ? 前置后置--
- ++? ? ? ? ? ? ? ? 前置后置++
- *? ? ? ? ? ? ? ? ? ?間接訪問操作符(解引用操作符)
- (類型)? ? ? ? ? ?強制類型轉(zhuǎn)換
?這些操作符我們大多數(shù)都知道,下面我們僅僅講解一下不是那么熟悉的:
sizeof????????操作數(shù)的類型長度
sizeof 計算的結(jié)果是 size_t 類型
size_t 是無符號整型
對 size_t 類型的數(shù)據(jù)進行打印,可以使用%zd或%u
int a = 10;
printf("%zd",sizeof(a));
結(jié)果為4。?
~? ? ? ? ? ? ? ? ? 對一個數(shù)的二進制按位取反
int a = 0;
printf("%d",~a);
0的補碼二進制序列為:
00000000 00000000 00000000 00000000
111111111 111111111 111111111 111111111//為負數(shù),取原碼
111111111 111111111 111111111 111111110//反碼
10000000 00000000 00000000 00000001//原碼
結(jié)果為-1。
*? ? ? ? 間接訪問操作符
int a = 10;
int* p = &a;
*p;//這時候我們的*就是對p進行解引用操作,*p是通過p中存放的地址,找到p指向的對象。
*p 其實就是a。
(類型)? ? ? ? ? ?強制類型轉(zhuǎn)換
int a = (int )3.14;
3.14在編譯器中會被默認為是double類型,如果直接將其初始化給int型的a,則會在后續(xù)操作中出現(xiàn)誤差甚至錯誤,所以要將其強制類型轉(zhuǎn)化為int型。
總結(jié)
本期關(guān)于操作符的知識講解到這里就要結(jié)束啦,稍后博主將更新C語言基礎(chǔ)之——操作符(下)來講解剩余的操作符。文章來源:http://www.zghlxwxcb.cn/news/detail-668589.html
喜歡博主文章的小伙伴們不要忘記一鍵三連哦,我們下期再見!文章來源地址http://www.zghlxwxcb.cn/news/detail-668589.html
到了這里,關(guān)于C語言基礎(chǔ)之——操作符(上)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!