運算子知識比較雜亂,這里我按照優先級從高向低的順序進行整理,優先度越高運算中約先進行
由于本人能力有限,有一些遺漏或者錯誤還希望大家斧正
文章目錄
- 優先度最高((),[ ],->,.)
- 優先級2級(!,~,++,- -,-(負號),*(指標),&(取地址),sizeof)
- 優先級3級(*(乘法),/,%)
- 優先度4級(+,-(減))
- 優先度5級(<<,>>)
- 優先度6級(<,>,>=,<=,)
- 優先度7級(==,!=)
- 優先度8級(&(按位與),|,^)
- 優先度9級(&&,| |)
- 優先度10級(?:)
- 優先級11級(=,+=,-=,*=,/=,%=,>>=,<<=,&=,^=,|=)
- 優先級12級(,(逗號運算式))
優先度最高((),[ ],->,.)
1,( )運算子
含義:函式呼叫運算子,
運算元是函式名以及函式內部的傳引數,
eg: test()運算元是函式名test,
test(x,y)運算元是test ,x,y(函式名+內部的傳引數)
注意函式呼叫運算子只要是函式就必須有
eg: sizeof()的括號可以省略,說明sizeof不是函式,是一種運算子,
強制型別轉化
(強制轉化型別)
#include <stdio.h>
int main()
{
int a =(int)3.14 ;
printf("a=%d ",a);
return 0;
}

結合性(同優先級運算子在陳述句中的“運算優先級(或叫順序) 從左向右,
2,[ ]運算子
含義:下標運算運算子
eg:
arr[4] 運算元為arr和4,
結合性:從左向右
3,->運算子
含義:指向結構體成員運算子,
eg:
#include<stdio.h>
struct student
{
//結構體的成員
char name[20];
int age;
char sex[5];
};
int main()
{
//結構體訪問運算子是建立在結構體上的
struct student s = { "小紅",18,"woman" };//初始化結構體
struct student* ps = &s;
/*printf("%s",(*ps).name);*/
printf("%s",ps->name);
return 0;
}

作用:通過指標找到結構體變數中的成員,
結合性:從左向右,
4, . 運算子
含義:結構體成員運算子,
eg:
#include<stdio.h>
struct student
{
//結構體的成員
char name[20];
int age;
char sex[5];
};
int main()
{
//結構體訪問運算子是建立在結構體上的
struct student s = { "小紅",18,"woman" };//初始化結構體
printf("%s",s.name);
return 0;
}

#include<stdio.h>
struct student
{
//結構體的成員
char name[20];
int age;
char sex[5];
};
int main()
{
//結構體訪問運算子是建立在結構體上的
struct student s = { "小紅",18,"woman" };//初始化結構體
struct student* ps = &s;
printf("%s",(*ps).name);
return 0;
}

用來找到結構體變數中的成員,
結合性:從左到右
優先級2級(!,~,++,- -,-(負號),*(指標),&(取地址),sizeof)
1,!運算子
含義:邏輯非運算(單目運算子)
由真到假,由假到真(0為假,非0為真默認為1)
#include<stdio.h>
int main()
{
int a = 0;
int b = 6;
printf("a=%d b=%d",!a,!b);
return 0;
}

資料的多組輸入
#include <stdio.h>
int main()
{
int x = 0;
while (scanf("%d", &x) != EOF)
{
if (x >= 140)
printf("Genius\n");
else
printf("Not Genius\n");
}
return 0;
}

(檔案讀取到最后回傳一個EOF,EOF本質是-1為真,!EOF為0,程式就會停下來來實作多組輸入)
在判斷陳述句中使用
#include <stdio.h>
int main()
{
int input = 0;
if (!input)//如果input為假執行
{
//....
}
if (input)//如果input為真執行
{
//....
}
return 0;
}
結合性:從右向左
2, ~運算子
含義:按位取反運算子(單目運算子)
(按二進制位取反)
方法:
真變假,假變真,
在二進制位中0變1,1變0;
-----------------------------------------------------------------
首先我們要知道
整數在計算機中存的是它的補碼
原碼——>反碼——>補碼
三者的運算規則為
原碼按位取反(符號位不變)——>反碼,
反碼+1——>補碼,
在32位計算機中首位是符號位
表示正負不表示大小,
首位為1表示負數,首位為0表示正數,
eg(都是32位)
10000000000000000000000000000001表示-1
00000000000000000000000000000001表示1
對于正整數規定,它的原碼,反碼,補碼都相同可以直接用,
對于負數計算機存的補碼不等,要轉成原碼才可以直到其大小,
eg:
1 1 1 1 1…1 1(32位)(符號位1說明是負數)補碼
1 1 1 1 1…1 0(32位)(補碼-1到反碼)
1 0 0 0 0…0 1(32位)(符號位不變其余位按位取反到原碼)
原碼首位為1說明是負數,發現值數字-1,
-----------------------------------------------------------------
所以-1在計算機中儲存的是32個1
-1取反為32個0是0
而檔案讀取失敗回傳EOF本質是-1
0在計算機會判斷為假
所以連續輸入還可以寫為
int main()
{
int x = 0;
while (~scanf("%d", &x) )
{
if (x >= 140)
printf("Genius\n");
else
printf("Not Genius\n");
}
return 0;
}
3,++運算子
含義:自增運算子(單目運算子)
分為前置++和后置++(他們運算順序不同)
前置++
先++再在使用,
#include <stdio.h>
int main()
{
int a = 10;
int b = ++a;
printf("a=%d b=%d",a,b);
return 0;
}

#include <stdio.h>
int main()
{
int a = 10;
printf("a=%d ",++a);
return 0;
}

后置++
先使用再++
#include <stdio.h>
int main()
{
int a = 10;
int b = a++;
printf("a=%d b=%d",a,b);
return 0;
}

#include <stdio.h>
int main()
{
int a = 10;
printf("a=%d ",a++);
return 0;
}

這里因為是先使用所以a沒有自增就被列印了出來,
結合性從右向左
4,- -運算子
含義:自減運算子(單目運算子)
分為前置- -和后置- -
前置- -
先- -再使用
#include <stdio.h>
int main()
{
int a = 10;
int b = --a;
printf("a=%d b=%d",a,b);
return 0;
}

#include <stdio.h>
int main()
{
int a = 10;
printf("a=%d ",--a);
return 0;
}

后置- -
先使用再- -
#include <stdio.h>
int main()
{
int a = 10;
int b = a--;
printf("a=%d b=%d",a,b);
return 0;
}

#include <stdio.h>
int main()
{
int a = 10;
printf("a=%d ",a--);
return 0;
}

這里因為先使用所以a還沒有自減就已經被列印
5,-符號運算子
含義:負號運算子(單目運算子)
優先級:從右向左
(注意負號運算子和減法運算子不同,負號運算子是單目運算子,減法運算子是雙目運算子,系統會自動識別)
#include <stdio.h>
int main()
{
int a = 10;
a = -a;//負號運算子
a = a - 10;//減法運算子
return 0;
}
6,* (指標)運算子
含義:指標運算子(單目運算子)
用來存放地址,或者找到指標變數所指物件,
(具體指標性質在之后提到)
#include <stdio.h>
int main()
{
int a = 5;
int* pr = &a;//存放地址
printf("%d",*pr);//找到指標變數所指物件
return 0;
}

結合性:從右向左
7,&(取地址)運算子
含義:地址運算子(單目運算子)
結合性:自右向左
通常伴隨指標使用不再贅述
8,sizeof 運算子
含義:長度運算子(單目運算子)
sizeof可以計算變數大小,也可以計算變數型別大小

(注意int[10]是陣列的型別)
當求變數大小時sizeof()括號可以省略
但當求到變數型別的大小時括號不可以省略

sizeof與strlen的區別
sizeof是運算子求大小,strlen是求字串長度函式其必須有()函式呼叫運算子
sizeof會計算\0的大小,而strlen不會計算\0的長度(\0)是字串結束的標志,
sizeof括號內的運算式是不會執行計算的
eg:
#include <stdio.h>
int main()
{
int s = 20;
int a = 10;
printf("%d\n",sizeof(s=a+5));
printf("%d",s);
return 0;
}

發現s在sizeof()內卻沒有計算,sizeof只計算了s型別的大小
(注意這個例子中決定sizeof值的是s的型別不是運算式中a的型別)
不計算的原因是
我們編譯的.c檔案會經過鏈接生成.exe可執行檔案
而sizeof(s=a+5)在編譯程序中就被替換成s型別的大小,所以就相當于s=a+5這個運算式在exe檔案中是2,所以不會i執行運算
結合性:從右向左
優先級3級(*(乘法),/,%)
1.*(乘法),/,%運算子
*(乘法)運算子 運算不在贅述;
/(除法)運算子
(注意要想通過除法得到一個浮點型,除數與被除數至少有一個要寫出小數)
#include <stdio.h>
int main()
{
float i = 3 / 2.0;
printf("%f",i);
return 0;
}
%(求余運算子)
(注意%不能有小數)
通常通過%來控制亂數的范圍,
或者得到數字的每一位,
也可以通過%2來得到數字二進制的每一位,
三者結合性:從左向右,
優先度4級(+,-(減))
1.+運算子
含義:運算(不在贅述)
2.-運算子
含義:減法運算子
(注意與負號運算子區分即可不再贅述)
二者的結合性:從左向右,
優先度5級(<<,>>)
1,<<運算子
含義:左移運算子(移動的是儲存在記憶體中二進制的補碼)
規則:左邊丟棄,右邊補零,
#include <stdio.h>
int main()
{
int a = -1;
a = a << 1;
printf("%d",a);
return 0;
}
分析:
-----------------------------------------------------------------
首先我們要知道
整數在計算機中存的是它的補碼
原碼——>反碼——>補碼
三者的運算規則為
原碼按位取反(符號位不變)——>反碼,
反碼+1——>補碼,
在32位計算機中首位是符號位
表示正負不表示大小,
首位為1表示負數,首位為0表示正數,
eg(都是32位)
10000000000000000000000000000001表示-1
00000000000000000000000000000001表示1
對于正整數規定,它的原碼,反碼,補碼都相同可以直接用,
對于負數計算機存的補碼不等,要轉成原碼才可以直到其大小,
eg:
1 1 1 1 1…1 1(32位)(符號位1說明是負數)補碼
1 1 1 1 1…1 0(32位)(補碼-1到反碼)
1 0 0 0 0…0 1(32位)(符號位不變其余位按位取反到原碼)
原碼首位為1說明是負數,發現值數字-1,
-----------------------------------------------------------------
a的二進制值在記憶體中為32個1

移動后
補碼變成1 1 1 1 1 …0(32位)
反碼 1 1 1 1 1…01(32位)
原碼 1 0 0 0 0…10(32位)
翻譯原碼是-2

結合性:從左向右,
2.>>運算子
含義:右移運算子
有兩種移動方式
1,算數右移
2,邏輯右移
算數右移:右邊丟棄,左邊補充符號位,
邏輯右移:右邊丟棄,左邊補充0,


vs2019使用的是算數右移
注意不要移動負數位
eg:
a=a>>-1(這種寫法編譯器不支持)
結合性:從左到右,
優先度6級(<,>,>=,<=,)
用于比較兩個數字的關系(這里不再贅述)
結合性:從左到右
優先度7級(==,!=)
1.==運算子
含義:判斷兩個值是否相同
注意(在C語言中一個等號是賦值,兩個等號是判斷是否相同,)
==判斷是否相同時不能判斷字串與字串相同
判斷字串相同用的是strcmp函式
結合性:從左向右
2,!=不等于運算子
結合性:從左向右
不在贅述
優先度8級(&(按位與),|,^)
1,&(按位與)運算子
方法:按照二進制位與
#include <stdio.h>
int main()
{
int a = 6;
int b = 4;
int c = a & b;
printf("%d",c);
return 0;
}
注意a,b的二進制位是32位的,這里因為篇幅有限只寫出有效部分
&相當于求交集,二進制位1代表真,0代表假
只有同時為真的時候按位的結果才為1,其余情況全部為0
a的二進制位 0 1 1 0
b的二進制位 0 1 0 0
-----------a&b 0 1 0 0
因為是正數,原碼=反碼=補碼
翻譯結果為4

結合性:從左到右,
2,| 按位或運算子
方法:
按位或相當與并集,只要二進制位上有1,則最后按位或的結果就為1.
#include <stdio.h>
int main()
{
int a = 6;
int b = 4;
int c = a | b;
printf("%d",c);
return 0;
}
a的二進制位 0 1 1 0
b的二進制位 0 1 0 0
------------a|b 0 1 1 0
發現a|b的結果與a相同為6

結合性:從左到右
3,^ 按位異或運算子
方法:二進制位相同是為0,二進制位不同為1
#include <stdio.h>
int main()
{
int a = 6;
int b = 4;
int c = a ^ b;
printf("%d",c);
return 0;
}
a的二進制位 0 1 1 0
b的二進制位 0 1 0 0
-----------a^b 0 0 1 0
翻譯后為2

優先度9級(&&,| |)
1,&& 邏輯與運算子
(注意與&區分,&&不是在二進制上來考慮的,只關心真偽)
在C語言中 0為假,非0為真,且計算機輸出的真值默認為1.
相當于交集
#include <stdio.h>
int main()
{
int a = 6;
int b = 4;
int c = a &&b;
printf("%d",c);
return 0;
}


(注意邏輯與操作可能會出現短路現象)
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a=%d b=%d c=%d d=%d",a,b,c,d);
return 0;
}

分析:
當把a改為1時就會正常
#include <stdio.h>
int main()
{
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a=%d b=%d c=%d d=%d",a,b,c,d);
return 0;
}

應用:
在 if 陳述句中使用if(a>1&&a<3)
表示 1<a<3;
結合性:從左到右
2,| | 邏輯或運算子
(同理也要和 | 區分)
相當于并集
#include <stdio.h>
int main()
{
int a = 0;
int b = 3;
printf("%d",a||b);
return 0;
}

同理注意邏輯或也存在短路現象
int main()
{
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++||++b || d++;
printf("a=%d b=%d c=%d d=%d i=%d",a,b,c,d,i);
return 0;
}

其原理與邏輯與相同
因為邏輯或前一個運算式為真則一定為真,所以編譯器會讓++b和d++都不執行,只執行了a++
應用:
用在 if 陳述句中
if(a>2||a<0)表示a>2或者a<0
結合性:從左向右,
從上面的分析可知&& 與| |都是會控制求值順序的
優先度10級(?:)
1,?: 條件運算子
三目運算子
格式:
運算式?成立時:不成立時
應用:代替if…else使代碼量減少
eg:求三個數最大值
#include <stdio.h>
int main()
{
int a = 0, b = 0, c = 0;
scanf("%d%d%d", &a, &b, &c);
int max = a > b ? a : b;//先比較a,b成立max=a不成立max=b;
int max2 = max > c ? max : c;//在于c比較大于c則max是最大值,否則c是最大值
printf("最大值是%d",max2);
return 0;
}

優先級:從右向左
優先級11級(=,+=,-=,*=,/=,%=,>>=,<<=,&=,^=,|=)
1,=
C語言中=是賦值操作,不在贅述
2,a+=1——a=a+1
其余的類似不在贅述
結合性:從右向左
優先級12級(,(逗號運算式))
1, , 逗號運算子(順序求值運算子)
含義:用逗號隔開的多個運算式,從左向右依次進行,整個運算式的結果就是最右邊運算式的結果,
(括號內的運算式都會計算)
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("%d",c);
return 0;
}
a=12 c=b=a+1=13

應用:使代碼簡潔
while(a>0) while(a=fun(),a>0)
{ {
運算式1; 可以寫成 運算式1;
運算式2; 運算式2;
a=fun(); }
}
結合性:從左到右,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/253479.html
標籤:其他
上一篇:百度網盤下載加速(pc端)
下一篇:Hfut | 集電競賽指南
