前言
C語言中運算子不多,但是有些相同的運算子都是在不同的運算式中,有不同的解釋意思,比如 * 號,在運算式中5*5表示乘號,在int *p表示指標,在 *p = 10中,又表示解參考,所以今天就來詳細的整理一下C語言中的運算子,做到心中有數,可以一眼識破,用途有哪些,重點不是記憶:是理解,兄弟們,要懂本質,
文章目錄
- 前言
- 運算子的分類
- 算術運算子
- 移位運算子
- 位運算子
- 賦值運算子
- 單目運算子
- 關系運算子
- 邏輯運算子
- 條件運算子
- 逗號運算式
- 下標參考符
- 函式呼叫符
- 結構體呼叫運算子
運算子的分類
注意:以下運算子都必須是英文的半角符號,
| 算術運算子 | + * / % |
|---|---|
| 移位運算子 | << 左移運算子 >> 右移運算子 |
| 位運算子 | &按位與 ^ 按位異或 |按位或 |
| 賦值運算子 | = += -= *= /= &= |= ^= |
| 單目運算子 | ! 邏輯反操作 - 負值 + 正值 & 取地址 sizeof 運算元的型別長度(以位元組為單位) ~ 對一數的二進制按位取反 -- 前置、后置-- ++前置 后置++ |
| 關系運算子 | > < <= >= == != |
| 邏輯運算子 | &&邏輯與 ||邏輯或 |
| 條件運算子 | exp1 ? exp2 : exp3 |
| 逗號運算式 | exp1, exp2, exp3, …expN |
| 下標參考 | [ ] 下標參考運算子 |
| 函式呼叫 | ( ) |
| 結構成員 | . 結構體.成員名 -> 結構體指標->成員名 |
算術運算子
+加;-減;*乘;/除;%取余(取模);
+ - * 沒什么好說的,大家都會用,
👀來看看這個 / 號;
?問:下面代碼的 a = ?
int a = 9 /2;
printf("%d",a);
答:結果為4;不是4.5;在C語言中:對于 / (?除號來說),執行的是整數除法,
對于:/ (?除號),執行的是整數除法,這句話的深度理解;
?問:下面代碼的 b = ?
double b = 9 /2;
printf("%d",b);
答:結果為:4;這說明,對于 / 來說,執行的是整數除法,型別與它無關;
?問:假如要得到小數的除法如何得到呢?
答:只要運算子 / (?除號) 兩邊的運算元,只要有一個運算元為浮點數(小數),即執行的為浮點數除法,即得到的值為小數;
double a = 9 / 2.0;
double b = 9.0 /2.0;
double c = 9.0 / 2.0;
a b c的結果都是小數:4.5
👀來看看取模運算子 %:
取模也就是取余,一個數對另一個數取余就是得到這個數的余數:
int a = 9 % 4;
printf("%d",a);
a 的結果為 1;就是 9除4 余數為1的結果:
有個記憶小技巧:取模可以想象成為一直磨掉一個數磨到不能再磨為止;比如:9 % 2,可以想象為 9 磨掉 2,在磨掉 2,再 磨掉 2,再 磨掉 2,剩下 1,磨不了了,結果就為1了,
注意:取模運算子%,兩邊的運算元必須為整數;下面,不為整數會報錯;

移位運算子
>>左移運算子 和<<右移運算子;
計算方式:
- 左移運算子就是左邊丟棄,右邊補0;
- 右移運算子分兩種:
- 邏輯右移:右邊丟棄,左邊補0;不管是不是正數還是負數(作為了解即可)
- 算術右移:右邊丟棄,左邊看是負數還是正數,負數補上1,負數補上0;(幾乎所有編譯器都是按照這種方式計算)
注意:
移位運算子,操作的都是二進制的數,
并且運算元都是整數,且右運算元不能位負數(了解即可)
👀看看左移運算子 <<:
?問:下面代碼的 b = ?
int a = 5;
int b = a<<1;
printf("%d",b);
結果為:10;
分析分析:a 是整數,在記憶體中以補碼的形式存盤,正數的補碼和原始碼時一致的,a 是 int 型別,占四個位元組;如下圖:

?問:下面代碼的 b = ?
int a = -1;
int b = a<< 1;
printf("%d",b);
結果為:-2;
分析圖如下:

👀看看右移運算子>>:
右移運算子,我們見到的都是屬于算術右移,因為,對于計算機的整數來說,分為,正數和負數,正數和負數的區分是通過高位的第一個位來區分的,0,表示正數,1表示負數;所以在執行有一運算子時候
>>,需要判斷右邊補上的是0還是1,這是根據你要操作的是負數還是正數決定的,
?問:下面代碼的 b = ?
這是正數情況:
int a = 5;
int b = a>> 1;
printf("%d",b);
結果:b= 2

?問:下面代碼的 b = ?
int a = -1;
int b= a>>1;
printf("%d",b);
結果為:b = -1;
分析圖如下:

總結:
m左移n位的結果:就是m × 2n;
m右移n位的結果:就是 m / 2n;
位運算子
&按位與
|按位或
^按位異或
注意:他們的運算元必須是整數的二進制數,
計算方式:
&按位與 ,位數都為1,結果才為1,其他情況為0;
|按位或 ,位數只要有一個為1,結果就為1,全為0結果才為0;
^按位異或,位數不同就為1,相同就為0;
👀看看&按位與:
?問:下面代碼的 c = ?
int a = 5;
int b = -2;
int c = a&b;
printf("%d",c);
結果為:c = 4
分析圖:

👀看看|按位或:
?問:下面代碼的 c = ?
int a = 4;
int b = -2;
int c = a|b;
printf("%d",c);
結果為:c = -2
分析圖如下:

👀看看^按位異或:
?問:下面代碼的 c = ?
int a = 5;
int b = -2;
int c = a^b;
printf("%d",c);
結果:c = -5
分析圖如下:

?問:位運算子有什么作用呢?
答: 可以計算一個數的二進制補碼中有多少個1
假如有個變數a ,而 a&1 就可以得到a的最后一位是0還是1;
如果要得到a 的二進制一共有多少個1,可以讓 a右移后,a>>1,得到的結果繼續與 1 按位與 a&1,用一個變數加回圈就可以統計 a 中有多少個1;
如下代碼:
int a = 15;
int count = 0;
int ret = 0;
int i = sizeof(int)*8;
while(i > 0)
{
ret = a & 1;
if(ret == 1)
count++;
a = a>>1;
i--;
}
printf("count = %d",count);
異或運算子還可以用于:不用創建第三個變數交換兩個整數
int a = 5;
int b = 6;
a = a^b;
b = a^b;
c = c^b;
printf("a = %d,b = %d ",a, b);
結果位: a = 6;b =5;
賦值運算子
賦值運算子是一個很棒的運算子,他可以讓你得到一個你之前不滿意的值,也就是你可以給自己重新賦值,
+=-=*=/= ``%=>>=<<= ``&=|=^=
其實這個運算子很簡單,基本沒什么可以講的,所以就跳過了;
單目運算子
! 邏輯反操作
- 負值
+ 正值
& 取地址
sizeof 運算元的型別長度(以位元組為單位)
~ 對一個數的二進制按位取反
-- 前置、后置--++ 前置、后置++
* 間接訪問運算子(解參考運算子)
(型別) 強制型別轉換
👀來看看! 邏輯反操作 :
就是把一個數按邏輯變為 0 或者 1;得到的結果為bool值.
int a =5;
a = !a;
printf("a = %d",a);
int b = 0;
b = !b;
printf("b = %d",b);
結果:a = 0;b=1;
👀來看看 :& 取地址,* 間接訪問運算子(解參考運算子) :
& 取地址,是取出變數的地址,如果對陣列名取地址,則取出的是整個陣列的地址;
* 間接訪問運算子(解參考運算子) ,在定義時候 * 表示變數是指標,在使用的時候, * 表示指標指向的變數,
int a = 10;&a 得到的是 a 的地址
int * p = &a;這里的* 表示 p是一個指標變數;
*p = 20;這里的*表示指標p所指向的變數a
//
//
int arr[10]={0};
&arr ,得到的是整個陣列的地址;
sizeof(&arr)得到的值為 40個位元組,這里&arr,表示整個陣列的位元組大小
sizeof(arr)得到的是 4個位元組,這里的陣列名為陣列首元素的地址,地址為4個位元組大小;
👀來看看 :sizeof 運算元的型別長度(以位元組為單位) :
- 首先必須認識,sizeof 不是函式,函式只能用函式呼叫符號(),來呼叫,而 sizeof,是不需要呼叫符號也可以使用的,
- sizeof(),計算的是括號里面的變數或者型別的位元組大小,與存放的資料無關;
- sizeof(),括號內的運算式,不參與計算,括號內的運算式在編譯階段就已經定好了,
int a = 10;
char arr[10] = "abcdef";
printf("%d",sizeof(a)); //結果:4
printf("%d",sizeof(int));//結果:4
printf("%d",sizeof a);//結果:4
printf("%d",sizeof(arr));//結果:10
printf("%d",sizeof(arr[0]));//結果:4
//
//
int a = 5;
short s = 10;
printf("%d",sizeof(s = a +2));// 這里的值為2,因為s的型別為short,
//s的值為7,但是在編譯階段就確定了,運行時候,不會改變下面的 s的值
printf("%d",s);//這里s結果為:10;
👀來看看 :~ 對一個數的二進制按位取反 :
就是對一個整數的二進制數補碼進行取反操作
int a = 0;
int b = ~a;
printf("b = %d",b);
結果:b = -1;
分析圖:

👀來看看 : -- 前置、 后置-- ++ 前置、 后置++
- - 前置減減,就是先減1后使用;++前置加加,就是先加1后使用;
后置- -,就是先使用,后減1;后置++,就是先使用,后加1;
//++和--運算子
//前置++和--
#include <stdio.h>
int main()
{
int a = 10;
int x = ++a; //先對a進行自增,然后對使用a,也就是運算式的值是a自增之后的值,x為11,
int y = --a; //先對a進行自減,然后對使用a,也就是運算式的值是a自減之后的值,y為10;
return 0;
}
//后置++和--
#include <stdio.h>
int main()
{
int a = 10;
int x = a++; //先對a先使用,再增加,這樣x的值是10;之后a變成11;
int y = a--; //先對a先使用,再自減,這樣y的值是11;之后a變成10;
return 0;
}
關系運算子
><<=>===!=
其實就是比較大小,回傳的值為bool值,0或者 1;
注意:在編程的程序中== 和=不小心寫錯,導致的錯誤,
邏輯運算子
&& 邏輯與,||邏輯或
邏輯與 && 就是 左右兩邊的運算元同時為真,結果為真;
注意要點:當最前面的運算元為假,后面的運算元就不執行了;
邏輯或 || 就是左右兩邊的運算元只要有一個為真,就為真;
注意要點:當最前面的運算元為真,后面的運算元就不執行了;
來看一道360面試題
?問:程式輸出的結果是什么?
#include <stdio.h>
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);
return 0;
}
結果為: a = 1 b =2,c =3 d =4;
分析:

記住邏輯&& 第一個運算元為0,后面的運算式都不用計算了,
?問:程式輸出的結果是什么?
#include <stdio.h>
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\nd = %d\n", a, b, c, d);
return 0;
}
結果: a = 1 b =3,c=3 d =4;
分析:

邏輯或 | | :當最前面的運算元為真,后面的運算元就不執行了;
條件運算子
exp1 ? exp2 : exp3
exp表示的是運算式
條件運算子通草用來書寫一些簡單的if else 陳述句;
如:
if (a > 5)
b = 3;
else
b = -3;
轉換成條件運算式,是什么樣?
int b = a > 5 ? 3:-3;
或者:
a > 5 ? b = 3: b = -3; //不常用
逗號運算式
exp1, exp2, exp3, …expN
逗號運算式最終的結果為expN,即逗號最后一個運算式的值;
通常我們在使用的時候,加上括號(),會使得代碼可讀性好,如(exp1, exp2, exp3, …expN);
//代碼1
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗號運算式
c是多少?
分析: a>b結果為 0,a =b+10,結果為12,b=a+1結果為 13;所以運算式化簡為:(0,12,13);所以結果為 13
結果:c = 13;
下標參考符
[ ]
下標參考符就是一個中括號的模樣,用于訪問陣列下標對應的值,
操作的資料:一個陣列名+一個索引下標
int arr[10]; //這是用于定義陣列
arr[9] = 10;//這是使用下標參考符訪問陣列
9[arr] 得到的是下標索引為9對應的值,深刻理解運算子,9和arr就是[ ]運算子的運算元;
我們要了解陣列名就是首元素的地址;
arr = &arr[0];
所以:arr+1 = &arr[1];
所以*(arr+1)= arr[1];
函式呼叫符
()
函式呼叫符號就是一個小括號
運算元為:函式名+引數串列(引數串列可以為空)
int test(int x);//這里是宣告函式的意思
int test(int x)//這里是定義函式的意思
{
}
test(10);//這里是呼叫函式的意思
結構體呼叫運算子
. 和 ->
運算元:自定義的變數 + 自定義型別里面的成員變數,計算的結果回傳的是右邊運算元的型別,
在C語言中,允許用戶自定義資料型別,通過struct關鍵字去定義:
如
struct student
{
char name[20];
int age;
};
這里自定義了一個型別為 struct student;里面包含了 name 陣列和 age 變數;假如你要訪問里面的變數的化,你可以通過自定義的型別 定義一個變數,通過結構體訪問符去訪問,
比如我要訪問 name陣列:
struct student s; //定義的型別 定義一個變數s
s.name ;//你訪問的就是name陣列
假如你是自定義型別的指標
struct student s;
s->name;//你訪問的就是name陣列
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/291540.html
標籤:其他
上一篇:掃雷優化版
