大家好我是Cbiltps,在我的博客中如果有難以理解的句意,難以用文字表達的重點,我會有配圖。所以我的博客配圖非常重要?。?!
如果你對我感興趣請看我的第一篇博客!
算數操作符有:
+ - * / %
除了%
操作符之外,其他的幾個操作符可以作用于整數和浮點數。
/
操作符#include int main(){ int ret = 9 / 2;//對于 /(除號) 兩邊都是整數,執行的整數除法 double ret2 = 9 / 2;//它的值是什么? double ret3 = 9 / 2.0;//它的值是什么? printf("%d/n", ret); printf("%lf/n", ret2); printf("%lf/n", ret3); return 0;}
運行結果如下:
第二個結果還是4.0
,為什么呢?
因為操作數中有浮點數,才執行浮點數除法。
%
操作符%
操作符是取模操作符,也叫取余操作符。
int ret4 = 10 % 4;printf("%d", ret4);//打印出來是2
注意:%
操作符只能針對整形類型
<< 左移操作符>> 右移操作符
<<
左移操作符int a = 5;int b = a << 1;printf("%d/n", b);//打印出來的是 10 //要看懂下面的圖解,要明白一些知識點: //移位操作符,移動的是二進制位 //對于整數的二進制有3中表示形式:原碼、反碼、補碼 //正整數 - 原碼、反碼、補碼相同 //負整數 //原碼 - 直接按照數字的正負寫出的二進制序列 //反碼 - 原碼的符號位不變,其他位按位取法得到的 //補碼 - 反碼+1 //整數 在內存中存儲的是二進制的補碼
如果是一個負數的話,看代碼:
int c = -1;int d = c << 1;printf("%d/n", d);//打印的是原碼的值,打印出來是 -2 //10000000000000000000000000000001 - 原碼 //11111111111111111111111111111110 - 反碼 //11111111111111111111111111111111 - 補碼
移位規則:左邊拋棄、右邊補0
關于原碼、反碼、補碼,請大家看我寫的另一篇進階博客!
>>
左移操作符移位規則:
1. 邏輯移位:左邊用0填充,右邊丟棄
2. 算術移位:左邊用原該值的符號位填充,右邊丟棄
舉例:
int a = 5;int b = a >> 1;printf("%d/n", b);//打印出來的是 2
再用負數舉個例子:
int c = -1;int d = c << 1;printf("%d/n", d);//打印出來還是 -1
在這里是補了原來的符號位,所以 VS2019 采用算術右移!
警告? :
1:對于移位運算符,不要移動負數位
,這個是標準未定義的。
2:不管是被移動數
還是移動的位數
都必須是整數。
例如(錯誤演示):
int num = 10;num>>-1;//error
位操作符有:
&
按位與|
按位或^
按位異或注:他們的操作數必須是整數。
&
按位與操作符計算規則:
1:二進制位上只要有0,那就是0
2:二進制位上兩個同時為1,那就是1
int a = 3; int b = -2; int c = a & b; printf("%d/n", c);//打印出來是 2 //%d - 說明我們要打印c的值,以有符號的形式 //00000000000000000000000000000011 -3的原碼 //11111111111111111111111111111110 -2的補碼 //00000000000000000000000000000010 這個數是2
|
按位或操作符計算規則: 二進制位只要有1,就為1
int a = 3;int b = -2;int c = a | b;printf("%d/n", c);//打印 -1 //00000000000000000000000000000011 -3的原碼 //11111111111111111111111111111110 -2的補碼 //11111111111111111111111111111111 //11111111111111111111111111111111 補碼 //11111111111111111111111111111110 反碼 //10000000000000000000000000000001 原碼 它的值是-1
^
按位異或操作符計算規則: 二進制位相同為0,相異為1
int a = 3;int b = -2;int c = a ^ b;//打印出來是 -3printf("%d/n", c); //00000000000000000000000000000011 -3的原碼 //11111111111111111111111111111110 -2的補碼 //11111111111111111111111111111101 //11111111111111111111111111111101 補碼 //11111111111111111111111111111100 反碼 //10000000000000000000000000000011 原碼 它的值是-3
一道{{BANNED}}的面試題:
不能創建臨時變量(第三個變量),實現兩個數的交換。
#include 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;}
思路圖解:
注意:這樣寫代碼的可讀性不夠好,而且只適用于整型
賦值操作符可以讓你得到一個你之前不滿意的值,也就是你可以給自己重新賦值。
int weight = 120;//體重weight = 89;//不滿意就賦值double salary = 10000.0;salary = 20000.0;//使用賦值操作符賦值
賦值操作符可以連續使用,比如:
int a = 10;int x = 0;int y = 20;a = x = y + 1;//連續賦值
這樣的代碼感覺怎么樣?
那這樣寫:
x = y + 1;a = x;
更加清晰爽朗而且易于調試。
復合賦值符:
這些運算符都可以寫成復合的效果,比如:
int x = 10;x = x + 10;x += 10;//復合賦值
單目操作符就是只有一個操作數的操作符
!
邏輯反操作
-
負值
+
正值
&
取地址
&arr[0];//數組首元素的地址&arr[9];//取出的是第10個元素的地址&arr;//取出數組的地址
sizeof
操作數的類型長度(以字節為單位)
//以下幾種寫法都是一樣的printf("%d/n", sizeof(a));//4printf("%d/n", sizeof a);//4printf("%d/n", sizeof(int));//4
//這里有一個問題;int a = 5;short s = 10;printf("%d/n", sizeof(s = a + 2));//打印出來是 2printf("%d/n", s); //打印出來是 10 因為:sizeof 內部的表達式不參與運算
~
對一個數的二進制按位取反
#incluide <stdio.h>int main(){ int a = 0; //00000000000000000000000000000000 int b = ~a; printf("%d/n", b); //00000000000000000000000000000000 //11111111111111111111111111111111 所有位按位取反 // //11111111111111111111111111111110 反碼 //10000000000000000000000000000001 原碼 //-1 return 0;}
--
前置、后置--
int a = 10;int b = a--;printf("%d/n", b);//這里打印出來還是 10
int a = 10;int b = --a;printf("%d/n", b);//這里打印出來才是9
++
前置、后置++
千萬注意:不要這樣子寫代碼(垃圾代碼),會被公司開除的!
int main(){ int a = 1; int b = (++a) + (++a) + (++a);//err printf("b=%d/n", b); return 0;}
這里兩個編譯器下不一樣!
*
間接訪問操作符(解引用操作符),可以和&
取地址搭配使用
(類型
) 強制類型轉換
int a = (int)3.14;//默認寫出的浮點數是double的,所以可以強制轉換printf("%d/n", a);return 0;
我們來看一個題,看它們分別輸出的是多少:
#include void test1(int arr[])//它的本質數是(int* arr[]){ printf("%d/n", sizeof(arr));//傳的是首元素的地址}void test2(char ch[]){ printf("%d/n", sizeof(ch));//(4)}int main(){ int arr[10] = { 0 }; char ch[10] = { 0 }; printf("%d/n", sizeof(arr));//數組名多帶帶放在sizeof內部,數組名表示整個數組 printf("%d/n", sizeof(ch));//(3) test1(arr); test2(ch); return 0;}
輸出結果:
更多關于數組的知識請看我的上一篇博客!
關系操作符在同類之間比較才有意義!
>
>=
<
<=
!=
用于測試“不相等”==
用于測試“相等”這些關系運算符比較簡單,沒什么可講的,但是我們要注意一些運算符使用時候的陷阱。
注意:在編程的時候 =
和 ==
寫錯,會導致出錯!
&&
邏輯與int a = 0;int b = 3;int c = a && b;//只判斷真假,所以打印出來是 0
||
邏輯或int a = 0;int b = 3;int c = a || b;printf("%d/n", c);//打印出來是 1
來看一道 360 的筆試題:
#include int main(){ int i = 0, a = 0, b = 2, c = 3, d = 4; i = a++ && ++b && d++; //i = a++||++b||d++; printf(" a = %d /n b = %d /n c = %d /nd = %d/n", a, b, c, d);//打印出來的是1 2 3 4 return 0;}
思路圖解:
那如果是邏輯或的話:
#include int main(){ int i = 0, a = 0, b = 2, c = 3, d = 4; i = a++ || ++b || d++; printf(" a = %d/n b = %d /n c = %d/n d = %d/n", a, b, c, d);//打印錯來的是1 3 3 4 return 0;}
思路圖解:
條件操作符也叫三目操作符
exp1 ? exp2 : exp3
int a = 0;int b = 0;if (a > 5) b = 3;else b = -3; //這里有更簡單的寫法:(a > 5) ? (b = 3) : (b = -3);//直接搞定
exp1, exp2, exp3, …expN
逗號表達式,就是用逗號隔開的多個表達式。
逗號表達式規則:從左向右依次執行,整個表達式的結果是最后一個表達式的結果
。
代碼演示:
//代碼1int a = 1;int b = 2;int c = (a>b, a=b+10, a, b=a+1);//c是多少?看的是最后一個表達式//代碼2if (a =b + 1, c=a / 2, d > 0)//最后一個表達式判斷的是 d > 0
//代碼3a = get_val();count_val(a);while (a > 0)//注意;這樣寫非常的冗余{ //業務處理 a = get_val(); count_val(a);}//如果使用逗號表達式,改寫:while (a = get_val(), count_val(a), a > 0){ //業務處理}
[ ]
下標引用操作符
操作數:一個數組名 + 一個索引值
int arr[10];//創建數組arr[9] = 10;//實用下標引用操作符。//[ ]的兩個操作數是arr和9。
//下面表達的意思都是相同的 arr[4] -- > *(arr+4) --> *(4+arr) --> 4[arr]
( )
函數調用操作符
接受一個或者多個操作數:第一個操作數是函數名,剩余的操作數就是傳遞給函數的參數。
void test(){ printf("hehe/n");}int main(){ test();//這里就是函數調用操作符 return 0;}
結構成員訪問操作符
.
結構變量.成員名->
結構體指針->成員名#include struct Book{ char name[20]; float price; char id[10];};void print1(struct Book b){ printf("書名: %s/n", b.name);//在這里訪問結構體成員 printf("價格: %f/n", b.price); printf("書號: %s/n", b.id); //*(b.name);}void print2(struct Book* pb){ /*printf("書名: %s/n", (*pb).name); printf("價格: %f/n", (*pb).price); printf("書號: %s/n", (*pb).id);*/ printf("書名: %s/n", pb->name);//也可以這樣訪問 printf("價格: %f/n", pb->price); printf("書號: %s/n", pb->id);}int main(){ struct Book b = {"C語言程序設計", 55.5f, "C20190201"}; print2(&b); //print1(b); //結構成員訪問操作符 //結構變量.成員名 //結構體指針->成員名 //(*結構體指針).成員名 return 0;}
表達式求值的順序一部分是由操作符的優先級和結合性決定。
同樣,有些表達式的操作數在求值的過程中可能需要轉換為其他類型。
C語言的整型算術運算總是至少以缺省整型類型的精度來進行的。
為了獲得這個精度,表達式中的字符和短整型操作數在使用之前被轉換為普通整型,這種轉換稱為整型提升。
整型提升的意義:
表達式的整型運算要在 CPU 的相應運算器件內執行,CPU 內整型運算器 (ALU) 的操作數的字節長度
一般就是 int 的字節長度,同時也是 CPU 的通用寄存器的長度。
因此,即使兩個 char 類型的相加,在 CPU 執行時實際上也要先轉換為 CPU 內整型操作數的標準長
度。
通用 CPU(general-purpose CPU)是難以直接實現兩個8比特字節直接相加運算(雖然機器指令
中可能有這種字節相加指令)。所以,表達式中各種長度可能小于 int 長度的整型值,都必須先轉
換為 int 或 unsigned int,然后才能送入 CPU 去執行運算。
如何進行整體提升呢?
整形提升是按照變量的數據類型的符號位來提升的
char c1 = -1;//變量c1的二進制位(補碼)中只有8個比特位://1111111//因為 char 是有符號的 char//所以整形提升的時候,高位補充符號位,即為1//提升之后的結果是://11111111111111111111111111111111
char c2 = 1;//變量c2的二進制位(補碼)中只有8個比特位://00000001//因為 char 是有符號的 char//所以整形提升的時候,高位補充符號位,即為0//提升之后的結果是://00000000000000000000000000000001
注意:無符號整形提升,高位補0
//舉例:#include int main(){ char a = 3;//a是1byte - 8bit //00000000000000000000000000000011 //00000011 - a
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/119290.html
??蘇州程序大白一文從基礎手把手教你Python數據可視化大佬??《??記得收藏??》 目錄 ????開講啦?。。?!????蘇州程序大白?????博主介紹前言數據關系可視化散點圖 Scatter plots折線圖強調連續性 Emphasizing continuity with line plots同時顯示多了圖表 數據種類的可視化 Plotting with categorical da...
目錄 一、什么是C語言? 二、第一個C語言程序 代碼 程序分析 ?程序運行 一個工程中出現兩個及以上的main函數 代碼 運行結果 分析 三、數據類型 數據各種類型 為什么會有這么多的數據類型? 計算機單位 ?各個數據類型的大小 ?注意事項 數據類型的使用 四、變量和常量 變量的分類 變量的使用 變量的作用域和生命周期 ?常量 五、字符串+轉義字符+注釋 字符串 ?轉義字符 注釋 六、選擇語句 ?...
??蘇州程序大白一文教你學會微信小程序開發??《??記得收藏??》 目錄 ????開講啦?。。?!????蘇州程序大白?????博主介紹?前言?講講專享小程序有什么優勢? ?小程序文件分析?事件綁定?圖片問題?輪播圖swiper?自定義組件?生命周期?頁面生命周期?項目制作?緩沖事件?`es7 async`語法 ?觸底事件??下拉刷新頁面??css省略號??預覽大圖??購物車模擬??獲取地...
閱讀 1005·2023-04-25 15:42
閱讀 3598·2021-11-02 14:38
閱讀 2891·2021-09-30 09:48
閱讀 1432·2021-09-23 11:22
閱讀 3394·2021-09-06 15:02
閱讀 3191·2021-09-04 16:41
閱讀 611·2021-09-02 15:41
閱讀 2021·2021-08-26 14:13