亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一篇文章帶你了解C語言操作符

 更新時間:2021年09月17日 16:10:39   作者:bug 郭  
這篇文章主要以圖文結(jié)合的方式為大家詳細(xì)介紹了C語言操作符基礎(chǔ)知識,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助

操作符和表達(dá)式

我們在初始C語言已經(jīng)大致了解了操作符,我們今天一起詳細(xì)解剖操作符。

操作符

C語言操作符很多,但大致進(jìn)行分類后,有以下幾種操作符

//算數(shù)操作符
+ - * / %
//移位操作符
<<    >>
//位操作符
&  |
//賦值操作符
=  += -= *= /= ...
//單目操作符
sizeof() ! ++  -- & * 
//關(guān)系操作符
> >= < <= ==
//邏輯操作符
&& ||
//條件操作符
?:
//逗號表達(dá)式
 ,
//其他操作符
[] ()  ->  .   ...

算數(shù)操作符

算數(shù)操作符再常見不過,

加減乘除,取余。

+ - * /操作符和我們數(shù)學(xué)上的一樣。

值得注意的是

/

int c=10/3; 
   c=10.0/3;
   c=10/3.0; //c結(jié)果為3
   (double)c=10.0/3; //能計算出小數(shù)值

C語言中,/需要至少一個操作數(shù)為浮點(diǎn)數(shù),才能使結(jié)果為浮點(diǎn)數(shù),并且記得存在浮點(diǎn)數(shù)中。

%求余(取模)操作符

只能計算兩個整型之間的結(jié)果,結(jié)果也為整型。

在這里插入圖片描述

移位操作符

這里說的移位,指的是移動二進(jìn)制位。

有左移,右移操作符。

<<左移操作符

向左移動二進(jìn)制位

在這里插入圖片描述

可以看到二進(jìn)制左移后,a<<1a2倍,所以我們可以知道,左移一位,擴(kuò)大2倍。

左移n位擴(kuò)大2^n倍。

>>右移操作符

可想而知,右移操作符,也與左移效果類似,二進(jìn)制位向右移動一位。

右邊的二進(jìn)制丟棄,右邊的二進(jìn)制位,并不是添像左移操作符一樣添零,需要分情況討論。

移位又分為算數(shù)移位和邏輯移位。

算數(shù)移位就是右移時,左邊添加那一位是需要看二進(jìn)制的符號位,添加。添加的哪一位和符號位相同。

邏輯移位就是不管左移還是右移操作,添加哪一位都是添0。

但我們需要移動一個負(fù)數(shù)時,顯然邏輯移位會改變原數(shù)值得正負(fù)。

所以在一般的編譯器下都采用算數(shù)移位。

在這里插入圖片描述

可以看到右移操作原來的值縮小了2^n倍。

注意:左移和右移都要考慮移位后是否會溢出。

移位操作是針對移動正數(shù)位,

a>>-1這樣移位錯誤,C語言未定義。

位操作符

位操作,有&(按位與) , |(按位或),^(按位異或)~(按位取反)。

位操作符顧名思義,是針對二進(jìn)制位的操作,有兩個操作數(shù)進(jìn)行,二進(jìn)制位進(jìn)行操作運(yùn)算。

這里我們的二進(jìn)制位都是指的補(bǔ)碼,因為一個數(shù)以補(bǔ)碼的形式存放在內(nèi)存中。

//   00000000 00000000 00000000 00100010
//   00000000 00000000 00000000 11010110
// & 00000000 00000000 00000000 00000010  
// | 00000000 00000000 00000000 11110110
// ^ 00000000 00000000 00000000 11110100 
位操作符 作用
& 兩操作數(shù)二進(jìn)制位都為真(1)結(jié)果為真(1)否者為假(0)
| 兩操作數(shù)二進(jìn)制位為假(0)結(jié)果為假(0)否者為真(1)
^ 一真(1)一假(0)結(jié)果為真(1),否者為假(0)
~ 二進(jìn)制位按位取反,1變0,0變1

位操作符的應(yīng)用

//嘗試寫一下這個代碼
include <stdio.h>
int main()
{
    int num1 = 1; //00000000 00000000 00000000 00000001
    int num2 = 2; //00000000 00000000 00000000 00000010
    num1 & num2; // 00000000 00000000 00000000 00000000
    num1 | num2; // 00000000 00000000 00000000 00000011
    num1 ^ num2; // 00000000 00000000 00000000 00000011
    return 0;
}

一道面試題小試牛刀

不創(chuàng)建新的變量,實現(xiàn)兩個變量的交換。

//方法一
#include<stdio.h>
int main()
{
 int a=3; // 00000000 00000000 00000000 00000011
 int b=5; // 00000000 00000000 00000000 00000101
 a=a^b;  //  00000000 00000000 00000000 00000110
 b=a^b;  //  00000000 00000000 00000000 00000011
 a=a^b;   // 00000000 00000000 00000000 00000101
}

有趣的一道代碼,利用^按位異或?qū)崿F(xiàn)了兩數(shù)的交換。

^異或操作符的性質(zhì)

a^a=0;

a^0=a;

經(jīng)常利用這兩條性質(zhì)解題,寫出優(yōu)秀的代碼!

//方法二
#include<stdio.h>
int main()
{
  int a=3;
  int b=5;
  a=a+b;  //a=8
  b=a-b; // b=3
  a=a-b; // a=5
}

求一個整數(shù)存儲在內(nèi)存中二進(jìn)制1的個數(shù)

//方法一
#include<stdio.h>
int main()
{
 int n=10;
 int count=0;
 while(n)
 {
 	if(n%2==1)
 	{
 		count++;
 	}
 	n>>=1;
 }
 printf("輸入二進(jìn)制位1的個數(shù):%d",count);
}

在這里插入圖片描述

思考上面的代碼是否存在問題

當(dāng)n為負(fù)數(shù)時?

在這里插入圖片描述

可以看到程序?qū)恢彼姥h(huán)下去。

我們優(yōu)化一下!

//方法二
#include<stdio.h>
int main()
{
 	int i=0;
 	int count=0;
 	int num=-3;
 	for(i=0;i<32;i++)
 	{
 		if((num>>i)&1==1)   //移位并且判斷最后一位是否為1
 			count++;
 	}
	return 0;
}

在這里插入圖片描述

每次都要進(jìn)行32次循環(huán),我們是否可以再次優(yōu)化一下!

//方法三
#include <stdio.h>
int main()
{
    int num = -1; // 10000000 00000000 00000000 00000001
              //補(bǔ)碼  11111111 11111111 11111111 11111111
    int i = 0;
    int count = 0;//計數(shù)
    while(num)
    {                    
        count++;          
        num = num&(num-1);//丟棄最后一位1
    }
    printf("二進(jìn)制中1的個數(shù) = %d\n",count);
    return 0;
}

在這里插入圖片描述

上面這個代碼是不是很神奇,一般人想不到,這就是代碼的魅力!

賦值操作符

賦值操作符,我們再熟悉不過了。

我們可以通過賦值操作符,將一個變量改變成你想要的值!

#include<stdio.h>
int main()
{
 	int weight=180;
 	weight=125;  //不滿意可以改變
 	//連續(xù)賦值
 	int a=13,b=0,c=0;
 	a=b=c=6;
 	//連續(xù)賦值操作缺點(diǎn)不易調(diào)試
}

復(fù)合賦值操作符

+= -= *= /= %= …

可以看到很多復(fù)合賦值操作符

   a+=2; ===>   a=a+2;
   a*3;  ===>   a=a*3;
     //其他運(yùn)算符一個道理
   ....

這邊是復(fù)合賦值操作符,使用起來很簡單,也很方便!

單目操作符

//單目操作符就是只有一個操作數(shù)的操作符!
+   -   !   sizeof()   ++  --  ~  *  (類型)

+ -

這里的+ -都是單目操作符,并不是算數(shù)操作符中的+-!

    a=-5;  //-5這里的-指的是單目操作符!
    b=+5; //+5 +可以省略!


邏輯反操作符

 while(a!=0)   //這里就是!邏輯反操作符
 {
 	count++;   //a不為0count++;
 }
 while(!a)
 {
  count++;   //a為0count++;
 }

sizeof

是否感到很詫異,sizeof居然是操作符!

sizeof是比較特殊的一個操作符,并不是函數(shù)!

我們知道sizeof可以計算一個變量和類型的所占空間內(nèi)存大??!

int main()
{
    int a = -10;
    int* p = NULL;
    printf("%d\n", !2);
    printf("%d\n", !0);
    a = -a;
    p = &a;
    printf("%d\n", sizeof(a));
    printf("%d\n", sizeof(int));
    printf("%d\n", sizeof a);      //這樣寫行不行?
    printf("%d\n", sizeof int);//這樣寫行不行?
	return 0;
}

在這里插入圖片描述

可以看到當(dāng)sizeof計算一個類型時,不添加括號,就會報錯,然而計算一個變量的大小時卻可以省略括號!

總結(jié):sizeof計算類型所占內(nèi)存大小時,括號不可省略。sizeof(類型),計算變量所占內(nèi)存大小時,sizeof(變量),sizeof變量

將錯誤更改一下,看一下運(yùn)行結(jié)果!

在這里插入圖片描述

sizeof和數(shù)組

我們知道sizeof可以計算變量的空間大小,所以我們經(jīng)常通過sizeof計算一個數(shù)組的元素個數(shù)!

公式:sizeof(數(shù)組)/sizeof(數(shù)組的一個元素)

#include <stdio.h>
void test1(int arr[])
{
    printf("%d\n", sizeof(arr));//(2)
}
void test2(char ch[])
{
    printf("%d\n", sizeof(ch));//(4)
}
int main()
{
    int arr[10] = {0};
    char ch[10] = {0};
    printf("%d\n", sizeof(arr));//(1)
    printf("%d\n", sizeof(ch));//(3)
    test1(arr);
    test2(ch);
    return 0;
}

問:
(1)、(2)兩個地方分別輸出多少?
(3)、(4)兩個地方分別輸出多少?

我們先通過自己計算一下!

計算結(jié)果!

(1)40 (2) 40 (3)10 (4) 10

而運(yùn)行結(jié)果!

在這里插入圖片描述

可以看到,運(yùn)行結(jié)果并不是那樣!

我們在思考一下這個結(jié)果,為啥結(jié)果會是4?

我們明明是將數(shù)組,直接傳參過去 ,而通過sizeof計算的內(nèi)存大小卻不是,難道我們只傳參了一個地址過去?

在這里插入圖片描述

我們調(diào)試一下,發(fā)現(xiàn)就是假設(shè)的這樣,數(shù)組傳參并沒有將整個數(shù)組傳參過去,而是傳參了一個指針!

而我們在x86也就是32位平臺下,指針?biāo)純?nèi)存空間大小為4個字節(jié)。

++ --

 //前置++和--:
    #include <stdio.h>
    int main()
    {
        int a = 10;
        int x = ++a;
        //先對a進(jìn)行自增,然后對使用a,也就是表達(dá)式的值是a自增之后的值。x為11。
        int y = --a;
        //先對a進(jìn)行自減,然后對使用a,也就是表達(dá)式的值是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;
    }

總結(jié): 前置++,--先進(jìn)行自加操作,再使用!

后置++,--先使用再進(jìn)行自加操作!

關(guān)系操作符

> >= < <= == (判斷是否等于) !=(判斷不等于)

這些這是基本的關(guān)系操作符!

我們已經(jīng)很常見了,我們看一下關(guān)系操作符的運(yùn)行結(jié)果!

可以看到,當(dāng)判斷結(jié)果為真是,vs用1代表真,用0代表假。

在這里插入圖片描述

注意:我們在測試,結(jié)果是否相等時,用==而不是賦值操作符=。

邏輯操作符

邏輯操作符,有邏輯與&&,邏輯或||

當(dāng)我們要測試兩個表達(dá)式結(jié)果時,如果要同時滿足,使用邏輯與&&只需滿足其中一個表達(dá)式結(jié)果時使用邏輯或||

我們要區(qū)分邏輯操作符和位操作符按位與&,按位或|區(qū)別!

#include<stdio.h>
int main()
{
     int a=3;//00000000 00000000 00000000 00000011
	 int b=1;//00000000 00000000 00000000 00000001
	printf("%d\n",a&b);
	printf("%d\n",a|b);
	printf("%d\n",a&&b);
    printf("%d\n",a||b);
			
return 0;
}

在這里插入圖片描述

位操作符和邏輯操作符截然不同,一個是對整數(shù)的二進(jìn)制進(jìn)行操作,另一個是對表達(dá)式的結(jié)果進(jìn)行判斷!

&& 只有當(dāng)兩個表達(dá)式結(jié)果同時為真,結(jié)果才為真!

|| 只有當(dāng)兩個表達(dá)式結(jié)果同時為假,結(jié)果才為假!

邏輯表達(dá)式的特性!

#include<stdio.h>
int main()
{
 int a=3,b=5,c=6,i=0;
 i=a++&&++b;
 printf("%d %d\n",a,b);
 i=a++||++b;
 printf("%d %d\n",a,b);
return 0;
}

在這里插入圖片描述

我們可以看到,邏輯或||第二個表達(dá)式,并沒有執(zhí)行。

這是為什么呢!

總結(jié): 邏輯與&&當(dāng)執(zhí)行到表達(dá)式結(jié)果為假,便停止執(zhí)行,后面的表達(dá)式!

邏輯或||當(dāng)執(zhí)行到表達(dá)式結(jié)果為真,便停止執(zhí)行后面的表達(dá)式!

這就是我們常說的邏輯短路特點(diǎn)!

條件操作符

exp1 ? exp2 : exp3

條件操作符通常由3個表達(dá)式構(gòu)成!又叫(三目操作符)!

如果exp1表達(dá)式結(jié)果為真,執(zhí)行exp2,否者執(zhí)行exp3

可以看到與我們的判斷語句if類似!

#include<stdio.h>
int main()
{
   int a=5,b=3,max=0;
   //if判斷語句求最大值
	if(a>b)
	{
	 max=a;
	}
	else
	{
	 max=b;
	}
	//條件表達(dá)式
	a>b?max=a:max=b;
return 0;
}

可以看到條件表達(dá)式的優(yōu)點(diǎn),可以大大的簡化代碼!

逗號表達(dá)式

exp1,exp2,exp3...expN

表達(dá)式之間用,分隔開,這就是逗號表達(dá)式。

表達(dá)式特點(diǎn)

#include<stdio.h>
int main()
{
	int a=2,b=3,c=5;
	int i=(a++,b++,c);
	printf("a=%d b=%d c=%d i=%d",a,b,c,i);
return 0;
}

在這里插入圖片描述

可以看到表達(dá)式i=(a++,b++,c);結(jié)果i=5也就是最后一個表達(dá)式c的值。

逗號表達(dá)式運(yùn)算特點(diǎn):

表達(dá)式從左往右依次計算,最后一個表達(dá)式的值,便是整個逗號表達(dá)式結(jié)果的值!

其他操作符

[]下標(biāo)引用操作符 ()函數(shù)調(diào)用操作符 . ->結(jié)構(gòu)成員訪問操作符

[]下標(biāo)引用操作符

操作數(shù):一個數(shù)組名+一個索引值

int arr[10];//創(chuàng)建數(shù)組
    arr[9] = 10;//實用下標(biāo)引用操作符。
      // [ ]的兩個操作數(shù)是arr和9。

既然是兩個操作數(shù),那么兩個操作數(shù)可以交換位置嗎?

在這里插入圖片描述

可以看到arr[9]等價9[arr]

但是我們并不介意用9[arr]

()函數(shù)調(diào)用操作符

( ) 函數(shù)調(diào)用操作符
接受一個或者多個操作數(shù):第一個操作數(shù)是函數(shù)名,剩余的操作數(shù)就是傳遞給函數(shù)的參數(shù)。

#include <stdio.h>
    void test1()
    {
        printf("hehe\n");
    }
    void test2(const char *str)
    {
        printf("%s\n", str);
    }
    int main()
    {
        test1();//實用()作為函數(shù)調(diào)用操作符。
        test2("hello bit.");//實用()作為函數(shù)調(diào)用操作符。
        return 0;
    }

. :結(jié)構(gòu)體.成員名
->:結(jié)構(gòu)體指針->成員名

#include <stdio.h>
struct Stu
{
    char name[10];
    int age;
    char sex[5];
    double score;
};
void set_age1(struct Stu stu)
{
    stu.age = 18;
}
void set_age2(struct Stu* pStu)
{
    pStu->age = 18;//結(jié)構(gòu)成員訪問
}
int main()
{
    struct Stu stu;
    struct Stu* pStu = &stu;//結(jié)構(gòu)成員訪問
    
    stu.age = 20;//結(jié)構(gòu)成員訪問
    set_age1(stu);
    
    pStu->age = 20;//結(jié)構(gòu)成員訪問
    set_age2(pStu);
    return 0;
}

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • C語言中實現(xiàn)協(xié)程案例

    C語言中實現(xiàn)協(xié)程案例

    這篇文章主要介紹了C語言中實現(xiàn)協(xié)程案例,本文通過將協(xié)程與線程和異步回調(diào)進(jìn)行對比,以及具體實現(xiàn)案例,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++實現(xiàn)LeetCode(94.二叉樹的中序遍歷)

    C++實現(xiàn)LeetCode(94.二叉樹的中序遍歷)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(94.二叉樹的中序遍歷),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • c/c++基礎(chǔ)簡單易懂的快速排序算法

    c/c++基礎(chǔ)簡單易懂的快速排序算法

    這篇文章主要為大家介紹了c/c++基礎(chǔ)非常簡單易懂的快速排序算法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2021-11-11
  • 淺析c與c++中struct的區(qū)別

    淺析c與c++中struct的區(qū)別

    c與c++中struct的區(qū)別你是否了解,下面小編就詳細(xì)的為大家介紹一下
    2013-07-07
  • C語言中的二叉樹和堆詳解

    C語言中的二叉樹和堆詳解

    這篇文章主要介紹了C語言中的二叉樹和堆詳解,樹是一種非線性的數(shù)據(jù)結(jié)構(gòu),它是由n(n>=0)個有限結(jié)點(diǎn)組成一個具有層次關(guān)系的集合,把它叫做樹是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的,需要的朋友可以參考下
    2023-07-07
  • C語言中g(shù)etchar()的返回類型為什么是int詳解

    C語言中g(shù)etchar()的返回類型為什么是int詳解

    這篇文章主要給大家介紹了關(guān)于C語言中g(shù)etchar()的返回類型為什么是int的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • Sublime Text 3 實現(xiàn)C++代碼的編譯和運(yùn)行示例

    Sublime Text 3 實現(xiàn)C++代碼的編譯和運(yùn)行示例

    下面小編就為大家?guī)硪黄猄ublime Text 3 實現(xiàn)C++代碼的編譯和運(yùn)行示例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • C++鏈表類的封裝詳情介紹

    C++鏈表類的封裝詳情介紹

    這篇文章主要介紹了C++鏈表類的封裝,文章基于C++的相關(guān)資料展開主題的詳細(xì)內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-04-04
  • Dev C++編譯時運(yùn)行報錯source file not compile問題

    Dev C++編譯時運(yùn)行報錯source file not compile問題

    這篇文章主要介紹了Dev C++編譯時運(yùn)行報錯source file not compile問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • C++實現(xiàn)字符格式相互轉(zhuǎn)換的示例代碼

    C++實現(xiàn)字符格式相互轉(zhuǎn)換的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C++中實現(xiàn)字符格式相互轉(zhuǎn)換的方法,主要有UTF8與string互轉(zhuǎn)、wstring與string互轉(zhuǎn),感興趣的小伙伴可以了解一下
    2022-11-11

最新評論