關于C語言操作符的那些事(超級全)
前言
C語言中操作符不多,但是有些相同的操作符都是在不同的表達式中,有不同的解釋意思,比如 * 號,在表達式中5*5表示乘號,在int *p表示指針,在 *p = 10中,又表示解引用,所以今天就來詳細的整理一下C語言中的操作符,做到心中有數(shù),可以一眼識破,用途有哪些。重點不是記憶:是理解,兄弟們,要動本質。
操作符的分類
注意:以下操作符都必須是英文的半角符號。
算術操作符 | + * / % |
---|---|
移位操作符 | << 左移操作符 >> 右移操作符 |
位操作符 | &按位與 ^ 按位異或 |按位或 |
賦值操作符 | =?。健。健。健。健。Γ健。健 。蓿?/td> |
單目操作符 | ! 邏輯反操作 - 負值 + 正值 & 取地址 sizeof 操作數(shù)的類型長度(以字節(jié)為單位) ~ 對一數(shù)的二進制按位取反 -- 前置、后置-- ++前置 后置++ |
關系操作符 | > <?。迹健。荆健?= != |
邏輯操作符 | &&邏輯與?。壿嫽?/td> |
條件操作符 | exp1 ? exp2 : exp3 |
逗號表達式 | exp1, exp2, exp3, …expN |
下標引用 | [ ] 下標引用操作符 |
函數(shù)調用 | ( ) |
結構成員 | . 結構體.成員名 -> 結構體指針->成員名 |
算術操作符
+ 加; -減; *乘; /除;%取余(取模);
+ - * 沒什么好說的,大家都會用。
👀來看看這個 / 號;
❓問:下面代碼的 a = ?
double b = 9 /2; printf("%lf",b);
答:結果為4;不是4.5;在C語言中:對于 / (➗除號來說),執(zhí)行的是整數(shù)除法。
對于:/ (➗除號),執(zhí)行的是整數(shù)除法,這句話的深度理解;
❓問:下面代碼的 b = ?
double b = 9 /2; printf("%lf",b);
答:結果為:4.000000;這說明,對于 / 來說,執(zhí)行的是整數(shù)除法,類型與它無關;
❓問:假如要得到小數(shù)的除法如何得到呢?
答:只要操作符 / (➗除號) 兩邊的操作數(shù),只要有一個操作數(shù)為浮點數(shù)(小數(shù)),即執(zhí)行的為浮點數(shù)除法,即得到的值為小數(shù);
double a = 9 / 2.0; double b = 9.0 /2.0; double c = 9.0 / 2.0; a b c的結果都是小數(shù):4.5
👀來看看取模操作符 %
:
取模也就是取余,一個數(shù)對另一個數(shù)取余就是得到這個數(shù)的余數(shù):
int a = 9 % 4; a 的結果為 1;就是 9除4 余數(shù)為1的結果:
有個記憶小技巧:取??梢韵胂蟪蔀橐恢蹦サ粢粋€數(shù)磨到不能再磨為止;比如:9 % 2,可以想象為 9 磨掉 2,在磨掉 2,再 磨掉 2,再 磨掉 2,剩下 1,磨不了了,結果就為1了。
注意:取模操作符%
,兩邊的操作數(shù)必須為整數(shù);下面,不為整數(shù)會報錯;
移位操作符
>>
左移操作符 和<<
右移操作符;
計算方式:
左移操作符就是左邊丟棄,右邊補0;
右移操作符分兩種:
- 邏輯右移:右邊丟棄,左邊補0;不管是不是正數(shù)還是負數(shù)(作為了解即可)
- 算術右移:右邊丟棄,左邊看是負數(shù)還是正數(shù),負數(shù)補上1,負數(shù)補上0;(幾乎所有編譯器都是按照這種方式計算)
注意:
移位操作符,操作的都是二進制的數(shù)。
并且操作數(shù)都是整數(shù),且右操作數(shù)不能位負數(shù)(了解即可)
👀看看左移操作符 <<
:
❓問:下面代碼的 b = ?
int a = 5; int b = a<<1; printf("%d",b); 結果為:10;
分析分析:a 是整數(shù),在內存中以補碼的形式存儲,正數(shù)的補碼和源碼時一致的,a 是 int 類型,占四個字節(jié);如下圖:
❓問:下面代碼的 b = ?
int a = -1; int b = a<< 1; printf("%d",b); 結果為:-2;
分析圖如下:
👀看看右移操作符>>
:
右移操作符,我們見到的都是屬于算術右移,因為,對于計算機的整數(shù)來說,分為,正數(shù)和負數(shù),正數(shù)和負數(shù)的區(qū)分是通過高位的第一個位來區(qū)分的,0,表示正數(shù),1表示負數(shù);所以在執(zhí)行有一操作符時候
>>
,需要判斷右邊補上的是0還是1,這是根據(jù)你要操作的是負數(shù)還是正數(shù)決定的。
❓問:下面代碼的 b = ?
這是正數(shù)情況:
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;
位操作符
- &按位與
- | 按位或
- ^按位異或
注意:他們的操作數(shù)必須是整數(shù)的二進制數(shù)。
計算方式:
- &按位與 ,位數(shù)都為1,結果才為1,其他情況為0;
- |按位或 ,位數(shù)只要有一個為1,結果就為1,全為0結果才為0;
- ^按位異或,位數(shù)不同就為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
分析圖如下:
❓問:位操作符有什么作用呢?
答: 可以計算一個數(shù)的二進制補碼中有多少個1
假如有個變量a ,而 a&1 就可以得到a的最后一位是0還是1;
如果要得到a 的二進制一共有多少個1,可以讓 a右移后,a>>1,得到的結果繼續(xù)與 1 按位與 a&1,用一個變量加循環(huán)就可以統(tǒng)計 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);
異或操作符還可以用于:不用創(chuàng)建第三個變量交換兩個整數(shù)
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 操作數(shù)的類型長度(以字節(jié)為單位)
~ 對一個數(shù)的二進制按位取反
-- 前置、 后置-- ++ 前置、 后置++
* 間接訪問操作符(解引用操作符)
(類型) 強制類型轉換
👀來看看! 邏輯反操作 :
就是把一個數(shù)按邏輯變?yōu)?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;
👀來看看 :& 取地址,* 間接訪問操作符(解引用操作符) :
& 取地址,是取出變量的地址,如果對數(shù)組名取地址,則取出的是整個數(shù)組的地址;
* 間接訪問操作符(解引用操作符) ,在定義時候 * 表示變量是指針,在使用的時候, * 表示指針指向的變量。
int a = 10;&a 得到的是 a 的地址 int * p = &a;這里的* 表示 p是一個指針變量; *p = 20;這里的*表示指針p所指向的變量a // // int arr[10]={0}; &arr ,得到的是整個數(shù)組的地址; sizeof(&arr)得到的值為 40個字節(jié),這里&arr,表示整個數(shù)組的字節(jié)大小 sizeof(arr)得到的是 4個字節(jié),這里的數(shù)組名為數(shù)組首元素的地址,地址為4個字節(jié)大?。?
👀來看看 :sizeof 操作數(shù)的類型長度(以字節(jié)為單位) :
- 首先必須認識,sizeof 不是函數(shù),函數(shù)只能用函數(shù)調用符號(),來調用,而 sizeof,是不需要調用符號也可以使用的,
- sizeof(),計算的是括號里面的變量或者類型的字節(jié)大小,與存放的數(shù)據(jù)無關;
- sizeof(),括號內的表達式,不參與計算,括號內的表達式在編譯階段就已經(jīng)定好了。
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;
👀來看看 :~ 對一個數(shù)的二進制按位取反 :
就是對一個整數(shù)的二進制數(shù)補碼進行取反操作
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;
注意:在編程的過程中== 和=不小心寫錯,導致的錯誤。
邏輯操作符
&& 邏輯與,||邏輯或
邏輯與 && 就是 左右兩邊的操作數(shù)同時為真,結果為真;
注意要點:當最前面的操作數(shù)為假,后面的操作數(shù)就不執(zhí)行了;
邏輯或 || 就是左右兩邊的操作數(shù)只要有一個為真,就為真;
注意要點:當最前面的操作數(shù)為真,后面的操作數(shù)就不執(zhí)行了;
來看一道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;
分析:
記住邏輯&& 第一個操作數(shù)為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;
分析:
邏輯或 | | :當最前面的操作數(shù)為真,后面的操作數(shù)就不執(zhí)行了;
條件操作符
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;
下標引用符
[ ]
下標引用符就是一個中括號的模樣,用于訪問數(shù)組下標對應的值。
操作的數(shù)據(jù):一個數(shù)組名+一個索引下標
int arr[10]; //這是用于定義數(shù)組 arr[9] = 10;//這是使用下標引用符訪問數(shù)組 9[arr] 得到的是下標索引為9對應的值,深刻理解操作符,9和arr就是[ ]操作符的操作數(shù);
我們要了解數(shù)組名就是首元素的地址;
arr = &arr[0];
所以:arr+1 = &arr[1];
所以*(arr+1)= arr[1];
函數(shù)調用符
()
函數(shù)調用符號就是一個小括號
操作數(shù)為:函數(shù)名+參數(shù)列表(參數(shù)列表可以為空)
int test(int x);//這里是聲明函數(shù)的意思 int test(int x)//這里是定義函數(shù)的意思 { } test(10);//這里是調用函數(shù)的意思
結構體調用操作符
. 和 ->
操作數(shù):自定義的變量 + 自定義類型里面的成員變量,計算的結果返回的是右邊操作數(shù)的類型。
在C語言中,允許用戶自定義數(shù)據(jù)類型,通過struct關鍵字去定義:
如
struct student { char name[20]; int age; };
這里自定義了一個類型為 struct student;里面包含了 name 數(shù)組和 age 變量;假如你要訪問里面的變量的化,你可以通過自定義的類型 定義一個變量,通過結構體訪問符去訪問。
比如我要訪問 name數(shù)組:
struct student s; //定義的類型 定義一個變量s s.name ;//你訪問的就是name數(shù)組
假如你是自定義類型的指針
struct student s; s->name;//你訪問的就是name數(shù)組
總結
到此這篇關于C語言操作符的那些事的文章就介紹到這了,更多相關C語言操作符內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
VScode配置cuda開發(fā)環(huán)境的實現(xiàn)步驟
本文主要介紹了VScode配置cuda開發(fā)環(huán)境的實現(xiàn)步驟,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-07-07詳解如何將Spire.PDF for C++集成到C++程序中
Spire.PDF for C++ 是一個專業(yè)的 PDF 庫,供開發(fā)人員在任何類型的 C++ 應用程序中閱讀、創(chuàng)建、編輯和轉換 PDF 文檔,本文主要介紹了兩種不同的方式將 Spire.PDF for C++ 集成到您的 C++ 應用程序中,希望對大家有所幫助2023-11-11