国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

再識C語言(五)

BigTomato / 1122人閱讀

摘要:注不要移動負數位標準未定義行為這種行為屬于標準未定義行為語言中并沒有規定移動負數位。按進制位與規則兩個二進制數,有則為,全則為。為假的時候,打印語言中表示假,非表示真無論是正數還是負數。

C語言操作符詳解

目錄

一、算術操作符

二、移位操作符

三、位操作符

四、賦值操作符

五、單目操作符

六、關系操作符

七、邏輯操作符

八、條件操作符

九、逗號表達式

十、下標引用、函數調用和結構體成員操作符

?十一、表達式求值

十二、 操作符查閱表

總結


C語言中的操作符有:

算術操作符、移位操作符、位操作符、賦值操作符、單目操作符、關系操作符、邏輯操作符、

條件操作符、逗號表達式、下標引用操作符、函數調用操作符、結構成員訪問操作符

一、算術操作符

+(加) ?????? -(減) ?????? *(乘) ?????? /(除) ?????? %(取模)

?+(加)-(減)*(乘)與數學中的類似,這里就不過多的敘述了。

(1)% : 取模(取余)得到的是相除之后的余數

?(2)/ :除法 得到的是商

  • 當? /(除號)兩端都是整數時,執行的是整數除法,整數除法得到的結果是整數部分,小數部分直接舍去。
  • 兩端只要有一個浮點數,執行的就是浮點數的除法,浮點數除法默認保留6位小數。

總結:

  1. 除了 % 操作符之外,其他的幾個操作符可以作用于整數和浮點數。
  2. ?對于 /(除) 操作符如果兩個操作數都為整數,執行整數除法。而只要有浮點數執行的就是浮點數除法。
  3. % 操作符的兩個操作數必須為整數。返回的是整除之后的余數。

二、移位操作符

<<:左移操作符

>>:右移操作符

注:移位操作符的操作數只能是整數

移位操作符移動的是整數的二進制位

先了解一下C語言中的二進制位

二進制與十進制的轉換

例:二進制數:1 1 1 1 ---------> 1*2^3+1*2^2+1*2^1+1*2^0 = 15 (十進制)

??????? 二進制不好理解,可以想一想十進制的:? 1 2 3 ---------> 1*10^2+2*10^1+3*10^0 = 123

??????? 十進制:5? 轉換為二進制: 0101 ---------> 0*2^3 + 1*2^2 + 0*2^1 + 1*2^0 = 5

二進制、八進制、十進制、十六進制只是數值的表示形式

整數有三種二進制的表示形式:原碼、反碼、補碼

正整數:原碼、反碼、補碼相同

負整數:原碼、反碼、補碼不同,要進行計算!

正整數:int a = 5;a是整型,a占4個字節 -->32bit

直接將十進制數轉換成為對應的二進制數得到的是原碼

a的原碼:00000000000000000000000000000101

a的反碼:00000000000000000000000000000101

a的補碼:00000000000000000000000000000101

最高位0表示正數

負整數:int b = -5;b是整型,b占4個字節 -->32bit

負數原碼、反碼、補碼的計算:

原碼:直接將十進制數轉換成為對應的二進制數

反碼:原碼的符號位(最高位)不變,其他位按位取反

補碼:反碼+1

b的原碼:1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0? 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1

b的反碼:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0

b的補碼:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1

最高位1表示負數

整數在內存中存儲的是補碼

可以看一下內存中存儲是是不是補碼

使用-1來驗證

-1的原碼:1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0? 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1

-1的反碼:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0

-1的補碼:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

?十六進制數使用 0 1 2 3 4 5 6 7 8 9 a b c d e f 表示

二進制 1 1 1 1 是十進制的15;十六進制的 f 是十進制的15

ff ff ff ff 寫成二進制形式:

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

由此可以知道整數在內存中存儲的是補碼。

1、左移操作符: <<

移位規則: 左邊拋棄、右邊補0

正數:

#includeint main(){	int a = 5;	//將a在內存中存儲的二進制位向左移動兩位	int b = a << 2;	printf("%d/n", b);    printf("%d/n", a);	return 0;}

代碼分析

雖然變量a左移兩位后值發生了變化,但a的值不會發生變化,就相當于 b = a+1,b的值發生了變化,a的值不會變。

運行結果

?負數:

#includeint main(){	int b = -5;	//將b在內存中存儲的二進制位向左移動兩位	int c = b << 2;	printf("%d/n", c);	printf("%d/n", b);	return 0;}

代碼分析

?運行結果

?2、右移操作符: >>

(1)算術右移

規則:右邊丟棄,左邊補原來的符號位

(2)邏輯右移

規則:右邊丟棄,左邊補0(如果是負數,左邊補0得到的是正數)

算術右移與邏輯右移取決于編譯器,C語言中并沒有規定具體使用哪種右移。我們常見的編譯器下都是算術右移。

正數:

#includeint main(){	int a = 5;	//將a在內存中存儲的二進制位向右移動1位	int b = a >> 1;	printf("%d/n", b);	printf("%d/n", a);	return 0;}

代碼分析

運行結果

負數:

#includeint main(){	int a = -5;	//將a在內存中存儲的二進制位向右移動1位	int b = a >> 1;	printf("%d/n", b);	printf("%d/n", a);	return 0;}

代碼分析

運行結果

?由代碼的運行結果得到,當前編譯器采用的是算術右移(左邊補符號位)。

注:不要移動負數位

int a = 10;int b = a >> -2; //標準未定義行為

這種行為屬于標準未定義行為(C語言中并沒有規定移動負數位)。

三、位操作符

&:按位與??????? |:按位或??????? ^:按位異或

注:他們的操作數必須是整數,操作的是整數的補碼。

1、按(2進制)位與:&

規則:兩個二進制數,有0則為0,全1則為1。

#includeint main(){	int a = -3;	int b = -5;	int c = a & b;	printf("%d/n", c);	return 0;}

計算過程

?運行結果

2、按(2進制)位或:|

規則:兩個二進制數,有1則為1,全0則為0。

#includeint main(){	int a = 3;	int b = -5;	int c = a | b;	printf("%d/n", c);	return 0;}

計算過程

?運行結果

3、按(2進制)位異或:^

規則:兩個二進制數,相同為0,相異為1。

#includeint main(){	int a = 3;	int b = -5;	int c = a ^ b;	printf("%d/n", c);	return 0;}

計算過程

?運行結果

4、位操作符練習

不創建臨時變量(第三個變量),實現兩個數的交換。

方法一:

#includeint 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;}

運行結果

這種方法雖然可以實現不創建臨時變量交換兩個數的效果,但是當兩個數加起來的結果超過了整型的范圍就會出錯,這種方法不能滿足任意兩個整數的交換。

方法二:

#includeint main(){	int a = 3;	int b = 5;	printf("交換前:a=%d b=%d/n", a, b);	a = a ^ b;	b = a ^ b;//b = a ^ b ^ b 	a = a ^ b;//a = a ^ a ^ b	printf("交換后:a=%d b=%d/n", a, b);	return 0;}

?運行結果

?這種方法可讀性太差,實際中交換兩個變量應用最多的方法是創建臨時變量來進行交換。這里只是練習使用位操作符。

四、賦值操作符

1、= :賦值操作符

賦值操作符是一個很棒的操作符,他可以讓你得到一個你之前不滿意的值。也就是你可以給自己重新賦值。

	int a = 10;	a = 100; //賦值操作符

賦值操作符可以連續賦值,但是不建議這樣寫。

#includeint main(){	int a = 10;	int b = 0;	int c = 20;	a = b = c + 1;//連續賦值	printf("%d/n", a);	return 0;}

運行結果

上面的寫法等同于

    int a = 10;	int b = 0;	int c = 20;	b = c + 1;	a = b;

補充:

賦值操作符必須保證左邊是變量

  • ?左值,是可以放在等號左邊的,一般是一塊空間(變量)。
  • 右值,是可以放在等號右邊的,一般是一個值,或者是一塊空間的內容。

2、復合賦值符

+=:加等???????? -=:減等???????? *= :乘等??????? /=:除等???????? %=:取模等

>>=:右移等??????? <<=:左移等???????? &=:按位與等???????? |=:按位或等???????? ^=:按位異或等

#includeint main(){	int a = 10;	int b = -5;	int c = 0;	a += 10;//等同于:a = a + 10;	c ^= b;//等同于:c = c ^ b;	printf("%d/n", a);	printf("%d/n", c);	return 0;}

其他運算符一樣的道理。這樣寫更加簡潔。?

五、單目操作符

3 + 5:

  • 3 是左操作數
  • + 是一個操作符
  • 5 是右操作數

+ 有兩個操作數,它是雙目操作符

單目操作符只有一個操作數

!:邏輯反操作??????? -:負值??????? +:正值??????? &:取地址???????

sizeof:計算操作數的類型長度(以字節為單位)

~:對一個數的二進制按位取反????? ? --:前置、后置--(減1)?????? ++:前置、后置++(加1)

*:間接訪問操作符(解引用操作符)??????? (類型):強制類型轉換

1、!:邏輯反操作

將一個表達式的結果,真變為假,假變為真。

#includeint main(){	int flag = 0;	//flag 為假的時候,打印hehe	if (!flag)	{		printf("hehe/n");	}	return 0;}

C語言中0表示假,非0表示真(無論是正數還是負數)。

  • !真:表示假
  • !0:表示真,!0 的值為 1

2、? - :負值

#includeint main(){	int i = 0;	int a = -10;	int flag = 1;	for (i = 0; i < 10; i++)	{		printf("%d ", i * flag);		flag = -flag;	}	return 0;}

運行結果

?3、+:正值

這個符號沒什么用,對于正數加上+還是正數,對于負數加上+還是負數。

4、&取地址

#includeint main(){	int a = 10;	&a;//& - 取地址操作符,獲取變量的地址	return 0;}

5、sizeof:計算操作數的類型長度(以字節為單位)

#includeint main(){	int a = 10;	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };	printf("%d/n", sizeof(a));	printf("%d/n", sizeof(int));	printf("%d/n", sizeof a);//因為sizeof是操作符,所以不加括號也行    //下面這種寫法不可以,sizeof在計算變量大小時才可以省略括號,    //sizeof在計算類型大小時不可以將括號省略。建議在寫的時候都加上括號。	printf("%d/n", sizeof int);//error	//計算數組的大小:	printf("%d/n", sizeof(arr));	printf("%d/n", sizeof(int [10]));//int [10] ->是數組 arr 的類型	return 0;}

?運行結果

#includevoid test1(int arr[]){	printf("%d/n", sizeof(arr));}void test2(char ch[]){	printf("%d/n", sizeof(ch));}int main(){	int arr[10] = { 0 };	char ch[10] = { 0 };	printf("%d/n", sizeof(arr));	printf("%d/n", sizeof(ch));	test1(arr);	test2(ch);	return 0;}

代碼分析

運行結果

6、~ 按(內存中補碼的二進制)位取反

#includeint main(){	int a = 0;	int b = ~a;	printf("%d/n", b);	return 0;}

計算過程

0的補碼:00000000000000000000000000000000

按位取反(~0)后:

補碼:11111111111111111111111111111111
反碼:11111111111111111111111111111110
原碼:10000000000000000000000000000001

結果: - 1

~ 按位取反的使用:

#includeint main(){	int a = 10;	a |= (1 << 2);	printf("%d/n", a);	a &= ~(1 << 2);	printf("%d/n", a);	return 0;}

?運行結果

?7、++:前置、后置++(加1)

前置++:先++,后使用

#includeint main(){	int a = 10;	int b = ++a;	printf("a=%d b=%d/n", a, b);	return 0;}

運行結果

?后置++:先使用,再++

#includeint main(){	int a = 10;	int b = a++;//先將a的值賦給b,再++	printf("a=%d b=%d/n", a, b);	return 0;}

運行結果

#includeint main(){	int a = 10;	printf("%d/n", a++); //值為10	return 0;}
#includeint main(){	int a = 10;	printf("%d/n", ++a); //值為11	return 0;}

?8、 --:前置、后置--(減1)

前置--:先--,后使用

#includeint main(){	int a = 10;	int b = --a;//先將a的值賦給b,再++	printf("a=%d b=%d/n", a, b);	return 0;}

運行結果

??后置--:先使用,再--

#includeint main(){	int a = 10;	int b = a--;//先將a的值賦給b,再++	printf("a=%d b=%d/n", a, b);	return 0;}

運行結果

自增自減(++、--)不要整的太復雜

#includeint main(){	int a = 1;	int b = (++a) + (++a) + (++a);	printf("%d/n", b);	printf("%d/n", a);	return 0;}

?運行結果

同樣的代碼在Linux環境下使用 gcc 編譯器運行的結果

?由結果可以看出,這個代碼是一種錯誤的代碼,在不同的編譯器下運行會得到不同的結果。

?9、 *:間接訪問操作符(解引用操作符)

#includeint main(){	int a = 10;	int* pa = &a;	*pa = 20;//* ->解引用操作符(間接訪問操作符)	printf("%d/n", a);	return 0;}

?代碼分析

?運行結果

?10、(類型)強制類型轉換

#includeint main(){	int a =(int)3.14;//3.14 ->double類型	printf("%d/n", a);	return 0;}

?將double類型的數據強制類型轉換為整型后,得到是結果是整數部分,小數部分直接舍去。

運行結果

強制類型轉換不建議大量的使用,創建變量時盡量將類型匹配。

六、關系操作符

>:大于??????? >=:大于等于 ?????? <:小于??????? <=:小于等于??????? !=:不等于??????? ==:等于

關系操作符比較簡單,直接使用就可以了。

要注意:在編程的過程中容易將==和=不小心寫錯。==是用于測試兩個值相等,=是賦值。

七、邏輯操作符

&&:邏輯與??????? ||:邏輯或

區分邏輯操作符和按位操作符:

  • 按位與 & 和按位或 | :這兩個操作符是操作二進制位的。
  • 邏輯操作符:只關注變量值的真和假。

1、 &&:邏輯與

  • &&操作符左邊為假(0),就不會計算操作符右邊的表達式,整個表達式的結果為假。
  • 操作符左邊為真,會繼續計算操作符右邊的表達式。
  • 操作符兩邊只要有一個表達式的值為假,整個表達式的結果為假,值為0。
  • 只有兩個同時為真,整個表達式的結果才為真,值為1。

練習

#include int main(){    int i = 0, a = 0, b = 2, c = 3, d = 4;    i = a++ && ++b && d++;    printf("a = %d/nb = %d/nc = %d/nd = %d/n", a, b, c, d);    return 0;}

代碼分析

a=0,a++先返回a=0,a再自增(a的值為1)。當a返回的值為0時就不會再計算&&后面的表達式,所以,a的值為1,b的值為2,c的值為3,d的值為4。最會輸出結果,a = 1,b = 2 ,c = 3,d = 4。

運行結果

2、||:邏輯或

  • ||邏輯或操作符左邊為真,就不會計算操作符左邊的表達式,整個表達式的結果為真。
  • 操作符左邊為假,會繼續計算操作符右邊的表達式。
  • 操作符兩邊只要有一個表達式的值為真,整個表達式的結果為真,值為1。
  • 只有兩個都為假,整個表達式的結果為假,值為0。
#include int main(){    int i = 0, a = 0, b = 2, c = 3, d = 4;    i = a++||++b||d++;    printf("a = %d/nb = %d/nc = %d/nd = %d/n", a, b, c, d);    return 0;}

?代碼分析

a=0,a++先返回a=0,a再自增(a的值為1)。當a返回的值為0時計算 || 后面的表達式,b=2,++b先執行b自增1,再返回自增后的結果為3。當b=3時,表達式(++b)的結果為真,不會再計算||后的表達式。所以a的值為1,b的值為3,c的值為3,d的值為4。最會輸出結果,a = 1,b = 3 ,c = 3,d = 4。

運行結果

?總結

&&:左操作數為假,右邊不計算

||:左操作數作為真,右邊不計算

八、條件操作符

表達式1 ?? 表達式2 : 表達式3

如果表達式1的結果為真,則執行表達式2,整個表達式的結果為表達式2執行的結果

如果表達式1的結果為假,則執行表達式3,整個表達式的結果為表達式3執行的結果

#includeint main(){	int a = 10;	int b = 20;	int max = 0;	max = (a > b ? a : b);	printf("%d/n", max);	return 0;}

九、逗號表達式

表達式1,表達式2,表達式3 …… 表達式n

逗號表達式,就是由逗號隔開的多個表達式。

逗號表達式,從左向右依次執行。整個表達式的結果是最后一個表達式的結果。

#includeint main(){	int a = 3;	int b = 5;	int c = 6;	int d = (a += 2, b = a - c, c = a + 2 * b);	printf("%d/n", d);	return 0;}

代碼分析

  • 先計算,a += 2,a = 3 + 2 = 5
  • 再計算b = a - c,b = 5 - 6 = -1
  • 再計算c = a + 2 * b,c = 5 + 2 * (-1) = 3
  • d的結果為最后一個表達式的結果,所以輸出d的值為3。

運行結果

?逗號表達式的使用

#includeint main(){	int a = 5;	int count = 0;	while (count < 10)	{		a = a+1;		count++;	}	//簡潔的寫法	while (a = a + 1, count++, count < 10)	{		;	}	return 0;}

十、下標引用、函數調用和結構體成員操作符

1、 [ ],下標引用操作符

操作數:數組名+元素下標

#includeint main(){	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };	printf("%d/n", arr[7]);//[]就是下標引用操作符,arr 和 7是操作數	return 0;}

運行結果

補充:

其實編譯器在編譯arr[7]時,是將arr[7]轉換成 *(arr+7)再對數組訪問。

*(arr+7) :arr是數組首元素的地址,arr+7就表示從數組首元素來說找到第8個元素(數組下標是從0開始的,所以找到的是第8個元素)。

arr[7] ---> *(arr+7) --->*(7+arr) --->7[arr]

這里只是推導一下有這種形式,但在寫代碼的時候還是正常寫比較好。

2、 ( ) 函數調用操作符

接受一個或者多個操作數:第一個操作數是函數名,剩余的操作數就是傳遞給函數的參數。

無參函數,函數名就是操作數,有參函數,函數名和參數都是操作數。

3、訪問一個結構的成員

  • . ? 結構體.成員名
  • -> 結構體指針->成員名
#includestruct Stu{	char name[20];	int age;	double score;};int main(){	struct Stu s = { "zhangsan",20,85.5 };	// . 操作符	//結構體變量.結構體成員	printf("%s %d %.1f/n", s.name, s.age, s.score);	// -> 操作符	struct Stu* ps = &s;	printf("%s %d %.1f/n", (*ps).name, (*ps).age, (* ps).score);	//結構體指針->結構體成員	printf("%s %d %.1f/n", ps->name, ps->age, ps->score);	return 0;}

運行結果

?十一、表達式求值

表達式求值的順序一部分是由操作符的優先級和結合性決定。

有些表達式的操作數在求值的過程中可能需要轉換為其他類型。

1、隱式類型轉換

C的整型算術運算總是至少以缺省整型類型的精度來進行的。

為了獲得這個精度,表達式中的字符和短整型操作數在使用之前被轉換為普通整型,這種轉換稱為整型提升。

(1)整型提升的意義

表達式的整型運算要在CPU的相應運算器件內執行,CPU內整型運算器(ALU)的操作數的字節長度 一般就是int的字節長度,同時也是CPU的通用寄存器的長度。

因此,即使兩個char類型的相加,在CPU執行時實際上也要先轉換為CPU內整型操作數的標準長 度再計算。

通用CPU(general-purpose CPU)是難以直接實現兩個8比特字節直接相加運算(雖然機器指令 中可能有這種字節相加指令)。所以,表達式中各種長度可能小于int長度的整型值,都必須先轉 換為int或unsigned int,然后才能送入CPU去執行運算

(2)整型提升的計算過程

整型提升是按照變量的數據類型的符號位來提升的。

#includeint main(){	char a = 5;	char b = 126;	char c = a + b;	printf("%d/n", c);	return 0;}

執行過程

?運行結果

參與運算的數據類型是char和char計算,char和short計算,short和short計算都會發生整型提升。

整型提升的例子

(1)

#includeint main(){	char a = 0xb6;	short b = 0xb600;	int c = 0xb6000000;	if (a == 0xb6)		printf("a/n");	if (b == 0xb600)		printf("b/n");	if (c == 0xb6000000)		printf("c/n");	return 0;}

代碼分析

  • 變量 a 和 b要進行整形提升,但是變量c是整型所以不需要整形提升。
  • a和b整形提升之后就變成了負數,所以表達式 a==0xb6 , b==0xb600 的結果為假。
  • c不發生整形提升,所以表達式 c==0xb6000000 的結果是真. 所程序輸出的結果是: c

運行結果

(2)

#includeint main(){	char c = 1;	printf("%u/n", sizeof(c));	printf("%u/n", sizeof(+c));	printf("%u/n", sizeof(-c));	return 0;}

代碼分析

  • 變量c只要參與表達式運算,就會發生整形提升。
  • 表達式 +c 就會發生提升,所以 sizeof(+c) 是4個字節。表達式 -c 也會發生整形提升,所以 sizeof(-c) 是4個字節,但是 sizeof(c) ,就是1個字節。
  • 最后輸出的結果是:1 4 4

運行結果

補充:sizeof(),括號內的表達式不參與運算。

??? int a = 10;
?? ?int b = 20;
?? ?a + b;?????

  • 表達式有兩個屬性:值屬性,類型屬性
  • a+b 中:30就是值屬性,int就是類型屬性
  • 當知道類型屬性時,sizeof是通過類型屬性判斷表達式有幾個字節,所以不需要計算。表達式的值。
#includeint main(){	short s = 20;	int a = 5;	printf("%d/n", sizeof(s = a + 4));	printf("%d/n", s);	return 0;}

?代碼分析

  • a是整型,a+4表達式的類型是int,將a+4放到變量s中,但是s是short類型,所以表達式的類型就變成了short類型。所以sizeof計算的是short類型字節的大小,結果是2。
  • sizeof()括號中的表達式不會真實計算,所以s的值還是20。
  • 最后輸出的結果是 2? 20

運行結果

2、算術轉換

?如果某個操作符的各個操作數屬于不同的類型,那么除非其中一個操作數的轉換為另一個操作數的類 型,否則操作就無法進行。下面的層次體系稱為尋常算術轉換

  1. long double???????
  2. double???????
  3. float???????
  4. unsigned long int???????
  5. long int???????
  6. unsigned int???????
  7. int
  • 上面這些類型之間轉換是由下往上轉換。
  • 例:int 類型的數與flaot類型的數進行計算,最終計算的結果應該是float類型。

如果某個操作數的類型在上面這些列表中排名較低,那么首先要轉換為另外一個操作數的類型后執行運算。
?

#includeint main(){	int a = 5;	float b = 3.14;	float r = a + b;//算術轉換	return 0;}

小于4個字節的類型之間計算是整型提升,其他類型之間計算時算術轉換。

注: 算術轉換要合理,要不然會有一些潛在的問題。

3、操作符的屬性

復雜表達式的求值有三個影響的因素。

  1. 操作符的優先級
  2. 操作符的結合性
  3. 是否控制求值順序。

兩個相鄰的操作符取決于他們的優先級。如果兩者的優先級相同,取決于他們的結合性。

(1)操作符優先級

#includeint main(){	int a = 10;	int b = 20;	int c = a + b * c;	return 0;}

乘法的優先級高于加法,所以先計算乘法再計算加法。

(2)操作符結合性

相鄰操作符的優先級相同的情況下,取決于結合性。

#includeint main(){	int a = 10;	int b = 20;	int c = a + b + c;	return 0;}

加法的結合性是從左向右計算。所以先計算a+b,再將a+b計算出的結果與c進行計算。

一些問題表達式有了優先級和結合性也不能準確的確定表達式的計算結果

(1)代碼1

a * b + c * d + e * f

這個表達式沒有唯一確定的計算順序

第一種:

  1. 計算a * b
  2. 計算c * d
  3. 計算e * f
  4. 計算a * b? +? c*d
  5. 計算a * b? +? c * d + e * f

第二種:

  1. 計算a * b
  2. 計算c * d
  3. 計算a * b? +? c*d
  4. 計算e * f
  5. 計算a * b? +? c * d + e * f

如果a,b,c,d,e,f 每個都是一個表達式,那么兩種計算順序得到的結果肯定不同。

由于*比+的優先級高,只能保證,*的計算是比+早,但是優先級并不 能決定第三個*比第一個+早執行。

(2)代碼2

#includeint main(){	int c = 5;	c + --c;	return 0;}

?這個代碼中--的優先級高于+,但是c的取值不確定。

  1. 加號的左操作數先準備讓c=5,先計算--c,c = 4。5 + 4=9
  2. 加號的左操作數不準備,先計算--c,c = 4。4 + 4 = 8

操作符的優先級只能決定自減--的運算在+的運算的前面,但是我們并沒有辦法得知,+操作符的左操作數的獲取在右操作數之前還是之后求值,所以結果是不可預測的,是有歧義的。

(3)代碼3

#inclu           
               
                                           
                       
                 

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/124773.html

相關文章

  • JS魔法堂:再識instanceof

    摘要:一大家都知道一般就是用來檢查對象是否為類或子類的實例。中兩者均指向,因此添加到的屬性,也會出現在的中。四其實是建議實現者如采用的底層優化手段。因為中定義函數啥都一樣,所以底層實現可以不再生成一個新的,從而從空間和時間上降低消耗。 一、Breif                             大家都知道instanceof一般就是用來檢查A對象是否為B類或子類的實例。那問題是...

    gself 評論0 收藏0
  • PHP擴展開發系列01 - 我要成為一名老司機

    摘要:找找出別人擴展真么寫的。這次主要說了下寫擴展要準備的一些基本知識。比如不同編譯方式這個你看別的擴展源碼的時候就會注意到具體作用。后面再來慢慢學習老司機的各種姿勢。包括,函數,函數參數,函數返回值,對象,類,命名空間等等等。 PHP擴展開發系列01 - 我要成為一名老司機 1. 關于擴展的教程貌似挺全了,為啥還寫? 記錄下我寫擴展的歷程 自認為會寫的更容易理解 我的宗旨就是 先用再識 ...

    30e8336b8229 評論0 收藏0
  • 分鐘殺穿指針 pointer——C語言專題

    摘要:另外,通過指針可以更便捷地操作數組。在一定意義上可以說,指針是語言的精髓。野指針成因除了未初始化還有就是越界訪問或者指針指向空間已經釋放。所以不難知道兩個地址相減就是元素的個數,這個表達式的前提是兩個指針指向同一塊空間。 ...

    MycLambert 評論0 收藏0
  • 分鐘腳踩大小端模式——C語言進階

    摘要:我們常用的結構,就是小端模式,什么則為大端模式沒學我也不知道是個啥,但還是擺出來。 目錄 傳統藝能?過渡區?正片開始?共用體原理?字節順序?大小端存儲?共用體判斷...

    andong777 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<