溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C語言入門基礎(chǔ)之操作符的示例分析

發(fā)布時間:2021-08-05 09:30:00 來源:億速云 閱讀:159 作者:小新 欄目:開發(fā)技術(shù)

這篇文章給大家分享的是有關(guān)C語言入門基礎(chǔ)之操作符的示例分析的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

操作符

首先第一部分操作符

C語言入門基礎(chǔ)之操作符的示例分析

分類如上,具體不再用文字闡述。

算術(shù)操作符

首先算術(shù)操作符,有除號值得一講,若想得浮點數(shù),兩端操作數(shù)至少有一個為浮點數(shù),否則就算變量用float定義也不行。

int main()
{
	//除號任意兩端有浮點數(shù)則,進行浮點數(shù)除法
	//全為整數(shù)則進行整數(shù)除法
	float a = 5 / 2;
	printf("%f\n", a);//2.0000
	float b = 5.0 / 2;
	printf("%f\n", b);//2.5000
	float c = 5 / 2.0;
	printf("%f\n", c);//2.5000
	float d = 5.0 / 2.0;
	printf("%f\n", d);//2.5000
 
	return 0;
}

移位操作符

接下來是移位操作符,分為左移和右移,右移較復(fù)雜先不講,先講左移。按二進制位向左移動一位,即把32個bit的二進制序列寫出來,整體向左移動一位,左側(cè)移出去就刪去,右側(cè)補零。

當(dāng)然如果你寫的多的話就可以看出來左移一位即十進制數(shù)字乘以二。

具體看代碼

int main()
{
	//00000000 00000000 00000000 00001100 - 12
	//00000000 00000000 00000000 00011000 - 24
	int a = 12;
	int b = a << 1;
	printf("%d\n", b);
	//00000000 00000000 00000000 00000110 - 6
	//00000000 00000000 00000000 00001100 - 12
	int c = 6;
	int d = c << 1;
	printf("%d\n", d);
	//00000000 00000000 00000000 00000010 - 2
	//00000000 00000000 00000000 00000100 - 4
	int e = 2;
	int f = e << 1;
	printf("%d\n", f);
	//由2^0左移一位為2^1;
	//由2^1左移一位為2^2;
	//由2^2+2^3左移一位為2^3+2^4;
	//二進制左移一位即十進制乘以二
	return 0;
}

位操作符

接下來是位操作符,有按位與,按位異或和按位或,按位與和按位或是反義的。

具體方法是將兩個操作數(shù)的二進制位寫出來,相應(yīng)位對比。

按位與:有0則0,全1則1。

按位異或:相同為0,相異為1。(異或嘛~)

按位或:有1則1,全0才0。

具體看代碼

int main()
{
	int a = 3;
	int b = 5;
	//00000000000000000000000000000011 - a
	//00000000000000000000000000000101 - b
	//00000000000000000000000000000001 - a & b
	//對應(yīng)的二進制位有0就為0,全是1則為1
	int c = a & b;
	printf("%d\n", c);//1

	//00000000000000000000000000000011 - a
	//00000000000000000000000000000101 - b
	//00000000000000000000000000000110 - a ^ b
	//對應(yīng)的二進制位相同為0,相異為1
	int d = a ^ b;
	printf("%d\n", d);//6

	//00000000000000000000000000000011 - a
	//00000000000000000000000000000101 - b
    //00000000000000000000000000000111 - a | b
	//對應(yīng)二進制位有1就是1,全為0才得0
	int e = a | b;
	printf("%d\n", e);//7
	return 0;
}

賦值操作符沒什么好講的,也就把a=a+1簡寫成了a+=1這樣差不多的操作符。

單目操作符

接下來是單目操作符

邏輯反操作!

首當(dāng)其沖是邏輯反操作!,這就涉及到了真假的問題。C語言中規(guī)定非0就是真,只有0是假。所以!上一個任意不為零的數(shù)都是0,但!0呢,規(guī)定!0就為1。

sizeof是個操作符,這也是很多人會忽略的一點。

按位取反~,經(jīng)過上面移位和位操作符的講解,應(yīng)該不難得出按位取反的含義,就是把二進制位列出來然后1變0,0變1。

當(dāng)然不止上面這么簡單,正數(shù)是這樣,那負數(shù)呢?

首先負整數(shù)時有符號的整數(shù),二進制位最高位如果是0,則該數(shù)為正數(shù),如果時1,則為負數(shù)。

其實計算機在內(nèi)存中存儲整數(shù)的時侯呀,存儲的是二進制,這大家都知道。然而一個整數(shù)的二進制的表示形式有三種分別是 原碼,反碼,補碼

如果是正數(shù),那么原碼反碼補碼相同,那如果是負數(shù)呢,它的原反補是需要計算的。

其次我們應(yīng)該知道原反補是如何計算的。反碼,原碼符號位不變,其他位按位取反。補碼,反碼+1。

但是最重要也是最容易讓初學(xué)者混淆的一點是,計算機存儲整數(shù)時,往內(nèi)存里存的是補碼,而不是大多數(shù)人想象的原碼,這就需要我們反過來計算原反補了。

可以以0為例,0的二進制位全為0,所以可以看成是個正數(shù),所以其原反補相同。

如果我們想知道~0(對0按位取反)是個什么結(jié)果的話,

1.先對0的補碼按位取反的~0的補碼,

2.再反過來計算,補碼-1得反碼,

3.然后再符號位不變,其他按位取反得其原碼,

4.這樣就得到了~0的原碼,就可計算其十進制數(shù)了

由此可得的重要結(jié)論,對一個數(shù)按位取反,反的是二進制位的補碼!

int main()
{
	//整數(shù)在內(nèi)存中存儲的時候,存儲的是二進制
	//一個整數(shù)的二進制表示有3種形式:原碼,反碼,補碼
	//正整數(shù):原碼,反碼,補碼相同;
	//負整數(shù):原碼,反碼,補碼需計算;
	//有符號的整數(shù),最高位是0,表示為正,
	//              最高位是1,表示為負;
	//eg: 
	//  int a = 1;
	//00000000000000000000000000000001 - 原碼
	//00000000000000000000000000000001 - 反碼
	//00000000000000000000000000000001 - 補碼
	//  int a = -1;
	//10000000000000000000000000000001 - 原碼
	//11111111111111111111111111111110 - 反碼 - 符號位不變,其他位按位取反
	//11111111111111111111111111111111 - 補碼 - 反碼+1
	//內(nèi)存存儲整數(shù)時,存儲的是二進制的補碼
	//計算時也是從補碼開始計算
	//~按(二進制)位取反
	int b = 0;
	printf("%d\n", ~b);//-1
	//00000000000000000000000000000000 - 0的補碼
	//11111111111111111111111111111111 - ~0的補碼
	//11111111111111111111111111111110 - ~0的反碼
	//10000000000000000000000000000001 - ~0的原碼
	//故由0的補碼得~0的補碼,補碼-1得反碼,再(符號位不變)按位取反得原碼;
	//最后原碼代表的就是結(jié)果的二進制序列;
	return 0;
}
操作符++,--

操作符++,--,值得一提。很多學(xué)校喜歡考各種各樣的奇葩++--題,不同的編譯器得到的結(jié)果可能不同,所以那就是道錯題。

在真正編程時,使用++,--就老老實實使用。別搞別人看不懂的那一套,沒意思的,實力不是靠那個體現(xiàn)出來的。就分為前置和后置,也就是先++,在使用,還是先使用,再++的區(qū)別。

int main()
{
	int a = 2;
	//a = a + 1;
	//a += 1;
	//printf("%d\n", a);
	//前置++;后置++;
	int c = ++a;//前置++;先++,后使用
	printf("++a=%d\n", c);//3
	printf("  a=%d\n", a);//3
	a = 2;
	int d = a++;//后置++;先使用,后++
	printf("a++=%d\n", d);//2
	printf("  a=%d\n", a);//3
	a = 2;
	int e = --a;//前置--;先--,后使用
	printf("--a=%d\n", e);//1
	printf("  a=%d\n", a);//1
	a = 2;
	int f = a--;//后置--;先使用,后--
	printf("a--=%d\n", f);//2
	printf("  a=%d\n", a);//1

	return 0;
}

取地址操作符和解引用操作符是一對,放在指針部分再講。

關(guān)系操作符沒什么好講的,和數(shù)學(xué)上一個含義。

邏輯操作符

邏輯操作符嘛,就如同數(shù)學(xué)里的邏輯真假一樣,邏輯與和邏輯或,分別是并且和或者的關(guān)系,他們兩邊分別是兩個條件,如果兩個都為真,邏輯與表達式就為真。如果兩個有一個真的,邏輯或表達式就是真。

int main()
{
	//邏輯與 - &&(并且)
	//邏輯或 - ||(或者)
	int a = 1;
	int b = 4;
	if ((a = 1) && (b = 4))
	{
		printf("&&\n");
	}
	if ((a = 3) || (b = 4))
	{
		printf("||\n");
	}
	return 0;
}
條件操作符

條件操作符,x?y1:2,?的兩邊分別是兩個條件,前面的成立則整個表達式的值為1,反正則2。

逗號表達式

逗號表達式,( , , ,) ,如這樣的一個例子,每一個表達式都是一個算式,從左向右依次計算,最后一個表達式的結(jié)果作為整個逗號表達式的值。

//條件操作符(三目操作符)
int main()
{
	int a = 10;
	int b = 0;
	//if (a == 5)
	//{
	//	b = -6;
	//}
	//else
	//{
	//	b = 6;
	//}
	b = (a = 5) ? (6) : (-6);
	printf("%d\n", b);
	return 0;
}

//逗號表達式
//( , , ... , );
//表達式從左向右計算,整個表達式的結(jié)果為最后一個表達式的值
int main()
{
	int a = 0;
	int b = 3;
	int c = -1;
	int d = (a = b - 5, b = a + c, c = a + b, c -= 5);
	printf("%d\n", d);
	return 0;
}

OK,關(guān)于操作符的內(nèi)容就先介紹到這兒。

下面是關(guān)鍵字的內(nèi)容。

常見關(guān)鍵字

C語言入門基礎(chǔ)之操作符的示例分析

上圖為常見關(guān)鍵字的思維導(dǎo)圖,接下來請隨我一同探討。

這些是C語言里常見的各種關(guān)鍵詞,下面將對其部分稍作討論。

C語言入門基礎(chǔ)之操作符的示例分析

typedef

首先是typedef,翻譯來就是類型重命名。顧名思義,就是將定義變量的類型的名字如int,char等,重新取個名字代替。當(dāng)然一般用于非常長的類型名如unsigned int這樣,或者是結(jié)構(gòu)體類型。 如此之后就可以把unsigned int 改寫成 unint了。

//typedef 變量類型重命名
typedef unsigned int unint;

extern

然后是extern,翻譯過來就是外部的意思,故用于聲明引用外部(其他.c文件)的文件或者是函數(shù)等,但由于函數(shù)自帶外部鏈接屬性,所以一般不用于聲明外部函數(shù)。用法如extern int g_val;(g_val是外部的變量)

static

緊接著是static,它分別有修飾局部變量,修飾全局變量和修飾函數(shù)三種不同的用法,但個人認為修飾全局變量和函數(shù)的意義相同。

修飾局部變量

修飾局部變量時,使其出作用域不會被銷毀,準(zhǔn)確的來說就是延長了他的生命周期,但不影響作用域。

修飾全局變量和函數(shù)

修飾全局變量和函數(shù)時,會使其外部鏈接屬性失效,也是就使其不可以再其他源文件中被使用。

void test()
{
	//修飾局部變量
	//改變其生命周期,不影響作用域
	static int a = 1;
	a++;
	printf("%d ", a);
}
int main() 
{
	int i = 0;
	while (i < 10)
	{
		test();
		i++;
	}
	//static修飾全局變量
	printf("%d\n", g_val);

	int a = 10;
	int b = 20;
	//static修飾的函數(shù)
	int c = Add(a, b);
	printf("%d\n", c);

	return 0;
}
//static修飾全局變量
//使其不可跨文件使用(外部鏈接屬性失效)
static int g_val = 2021;
//static修飾的函數(shù)
//函數(shù)被static修飾,使其外部鏈接屬性變內(nèi)部鏈接屬性
static int Add(int x, int y)
{
	return x + y;
}

其它

其它如,auto,goto,register,union,稍微了解一下。

#define定義常量和宏

定義常量

定義常量時,也是非常簡單,例如:#define N 10; 就定義了一個不可被修改的常量其值為10。

定義宏

#define MAX(x,y) (x>y?x:y)

類似于函數(shù),但又有別于函數(shù),MAX(x,y)是宏,(x>y?x:y) 是宏體。MAX(x,y),像是函數(shù)名和傳參放在一塊,()就像是函數(shù)內(nèi)容。

//定義常量
#define NUM 100
//定義宏
#define MAX(X,Y) (X>Y?X:Y)
int main()
{
	printf("%d\n", NUM);
	int a = 0;
	int b = 10;
	int c = MAX(a, b);
	//實際操作,替換宏體
	//int c = (a > b ? a : b);
	printf("%d\n", c);
	return 0;
}

C語言入門基礎(chǔ)之操作符的示例分析

指針

指針一直是我之前自學(xué)的時候最害怕的內(nèi)容,但這次初識C語言讓我消除了對指針的恐懼,一步步的了解指針。

指針嘛,指向變量的內(nèi)存地址,故講指針之前必須把內(nèi)存搞清楚。

內(nèi)存單元

為了可以有效使用內(nèi)存,我們把內(nèi)存劃分了一個個小的內(nèi)存單元,每個內(nèi)存單元的大小為1byte。

我們需對內(nèi)存進行編號,當(dāng)然需要二進制位序列表示(默認我們是32位機器)。

每個二進制序列有32個bit,從數(shù)學(xué)全排列角度看,一共有2的32次方種排列可能(32個全0到32個全1)。

所以若想對其進行編號,不如一人一個碼(一個內(nèi)存單元用一個二進制序列表示)。并且我們把這些編號成為地址。

當(dāng)然,二進制也可以轉(zhuǎn)化為十進制或者十六進制,所以我們再調(diào)試時調(diào)用內(nèi)存會看到自動顯示為十進制數(shù)字。

C語言入門基礎(chǔ)之操作符的示例分析

我們了解了內(nèi)存,現(xiàn)在我們看看如何取出內(nèi)存的地址

int main()
{
    int num = 1;//先創(chuàng)建一個變量
    &num;//然后取出它的地址
    printf("%p",&num);//最后以%p的形式打印地址
return 0;
}

這樣我們就得到了num的地址,以十六進制數(shù)字展示。

指針變量

我們講清楚了內(nèi)存,現(xiàn)在再來看看指針。

我們既然已經(jīng)得到了地址,那我們?nèi)绾稳Υ孢@些東西呢,這是程序員們就想到了一種東西叫指針變量,它用于存放地址。

關(guān)于該(指針)變量如何定義看下列代碼。

#include <stdio.h>
int main()
{
    int num = 10;
    int *p = &num;
    *p = 20;
return 0;
}

上述代碼中我們可以看到,指針變量的類型時 int * 。而有了指針變量后,在其前面加上*有個可以改變原變量的值。當(dāng)然之所以是int*而不是char*,是因為原變量是int型的。

&取地址操作符,*解引用操作符

這里我們介紹一下,兩個操作符分別是&取地址操作符和*解引用操作符。

&+變量名 可以取出變量的地址。

*+指針變量名 就可以把它當(dāng)作原變量使用,通過這樣就可以進行改變原變量的這樣一系列的操作

可以說 pa = &a , *pa = a。

類型所占空間

那么我們既然知道了有種變量叫指針變量,那么他們的類型大小是多少呢?

答案是每種指針變量類型大小都為4個字節(jié)(32位機器),因為指針變量存放地址,地址為二進制序列,32個bit,正好占4個byte。當(dāng)然64位機器就是8個字節(jié)。

結(jié)構(gòu)體

結(jié)構(gòu)體的出現(xiàn)使得C語言具有了描述復(fù)雜類型的能力。

C語言的類型int,char,float等可以描述很多東西,但是這畢竟太單一,使用結(jié)構(gòu)體可以描述更復(fù)雜的對象。

比如最經(jīng)典的例子,如學(xué)生,書籍等。

定義結(jié)構(gòu)體

描述學(xué)生的信息有名字,性別,年齡,學(xué)號等,下面且與我一同欣賞如何定義學(xué)生結(jié)構(gòu)體。(記得大括號后面有個分號,vs2019自動帶上)

struct stu
{
	char name[20];//姓名
	int age;//年齡
	char sex[5];//性別
	char id[20];//學(xué)號
};

或者是針對書籍的描述,有書名,價格,作者名等

struct book
{
	char name[20];
	int price;
	char author[20];
};

注意,struct stu 這一整個相當(dāng)于 int float double 。

這樣我們就完成了結(jié)構(gòu)體變量類型的定義。

下面我們定義一個個的學(xué)生(結(jié)構(gòu)體)變量。

//創(chuàng)建結(jié)構(gòu)體變量
	struct stu s1 = {"蕪湖大司馬",40,"男","2020313222"};
	struct stu s2 = {"lisa",22,"女","2020313232"};
	struct book b1 = {"C語言詳解",55,"譚浩強"};

使用結(jié)構(gòu)體變量

創(chuàng)建好了我們?nèi)绾稳ナ褂媚兀孔詈唵蔚妮敵龇绞?,使用操作?.

形式上是 結(jié)構(gòu)體變量.成員名。

	//輸出1
	printf("name: %s,age: %d,sex: %s,id: %s\n", s1.name, s1.age, s1.sex, s1.id);
	printf("書名: %s,價格: %d,作者: %s\n", b1.name, b1.price, b1.author);

既然這樣可以的話,我們還可以定義指針變量代替變量名,用(*pb)代替b1。

	struct book * pb = &b1;
        //先定義一下指針變量
	printf("%s %d %s\n", (*pb).name, (*pb).price, (*pb).author);
        //指針變量解引用,就可以當(dāng)作原變量使用

當(dāng)然有更方便的操作符 ->,這樣我們可以直接使用指針啦,如結(jié)構(gòu)體指針->成員名。

	struct book * pb = &b1;
	//別忘了定義指針
	printf("%s %d %s\n", pb->name, pb->price, pb->author);
        //指針變量名直接加 —> 再加成員名

感謝各位的閱讀!關(guān)于“C語言入門基礎(chǔ)之操作符的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI