主頁 > 軟體設計 > C語言運算子的那些事(詳細全)

C語言運算子的那些事(詳細全)

2021-08-03 08:04:01 軟體設計

前言

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;就是 94 余數為1的結果:

有個記憶小技巧取模可以想象成為一直磨掉一個數磨到不能再磨為止;比如:9 % 2,可以想象為 9 磨掉 2,在磨掉 2,再 磨掉 2,再 磨掉 2,剩下 1,磨不了了,結果就為1了,

注意:取模運算子%,兩邊的運算元必須為整數;下面,不為整數會報錯;
在這里插入圖片描述


移位運算子

>> 左移運算子 和 << 右移運算子;

計算方式:

  • 左移運算子就是左邊丟棄,右邊補0;
  • 右移運算子分兩種:
  1. 邏輯右移:右邊丟棄,左邊補0;不管是不是正數還是負數(作為了解即可)
  2. 算術右移:右邊丟棄,左邊看是負數還是正數,負數補上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 運算元的型別長度(以位元組為單位) :

  1. 首先必須認識,sizeof 不是函式,函式只能用函式呼叫符號(),來呼叫,而 sizeof,是不需要呼叫符號也可以使用的,
  2. sizeof(),計算的是括號里面的變數或者型別的位元組大小,與存放的資料無關;
  3. 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

標籤:其他

上一篇:掃雷優化版

下一篇:要悄悄地學C語言,在成為大佬的路上一去不復返

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more