? ? 今日,我們即將踏上一段充滿趣味與挑戰的學習之旅,深度鉆研數據類型的多樣奧秘,解鎖變量創建的實用技巧。不僅如此,還會邂逅兩個實用的基礎庫函數,探索它們在程序中穿針引線的奇妙作用。同時,幾個簡潔卻強大的操作符也將揭開神秘面紗,為我們的代碼編寫增添更多靈活與高效。掌握這些知識,不僅是編寫代碼的入門功課,更是開啟 C 語言復雜應用大門的鑰匙,讓我們一同深入,領略其中的魅力與智慧 。
一、數據類型的介紹
? ? C語?提供了豐富的數據類型來描述?活中的各種數據。? ? 使?整型類型來描述整數,使?字符類型來描述字符,使?浮點型類型來描述?數。? ? 所謂“類型”,就是相似的數據所擁有的共同特征,比如:年齡是整型,‘c’是字符類型,編譯器只有知道了數據的類型,才知道怎么操作 數據。
下?盤點?下C語?提供的各種數據類型,本章節主要探討內置數據類型。
1.1 字符型
char //字符
[signed] char //有符號的字符類型
unsigned char //?符號的字符類型
1.2 整型
//短整型
short [int]
[signed] short [int] //有符號短整型
unsigned short [int] //無符號短整型//整型
int
[signed] int //有符號整型
unsigned int //無符號整型//?整型
long [int]
[signed] long [int] //有符號長整型
unsigned long [int] //無符號長整型//更?的整型
//C99中引?
long long [int] //長長整型
[signed] long long [int] //有符號長長整型
unsigned long long [int] //無符號長長整型
1.3 浮點型
float //單精度浮點型
double //雙精度浮點型
long double //擴展精度浮點數類型或者長雙精度浮點數類型
1.4?布爾類型
C 語?原來并沒有為布爾值單獨設置?個類型,?是使?整數 0 表?假,?零值表?真。在 C99 中也引?了 布爾類型 ,是專?表?真假的
_Bool bool //布爾類型這兩種表示方式都可以布爾類型的使用得包括頭文件#include<stdbool.h>布爾類型的取值范圍是:flase(假)或者true(真)//在C語言中0表示假,非0表示真
#include<stdbool.h>
#include<stdio.h>//代碼演示int main()
{bool flag = true;//初始化布爾類型的變量為真if (flag)//為真就執行下面的語句,為假就不執行下面的語句printf("i like C\n");return 0;
}
1.5 各種數據類型的?度
每?種數據類型都有??的?度,使?不同的數據類型,能夠創建出?度不同的變量,變量?度的不同,存儲的數據范圍就有所差異。
sizeof 是?個關鍵字,也是操作符,專?是?來計算sizeof的操作符數的類型?度的,單位是字
節。sizeof 操作符的操作數可以是類型,也可是變量或者表達式。1 sizeof( 類型 )2 sizeof 表達式
sizeof 的操作數如果不是類型,是表達式的時候,可以省略掉后邊的括號的。
?
sizeof 后邊的表達式是不真實參與運算的,根據表達式的類型來得出??。
?
sizeof 的計算結果是 size_t 類型的。?
? ? sizeof 運算符的返回值,C 語?只規定是?符號整數,并沒有規定具體的類型,?是留給系統??去決定, sizeof 到底返回什么類型。? ? 不同的系統中,返回值的類型有可能是 unsigned int ,也有可能是 unsigned long ,甚?是 unsigned long long , 對應的 printf() 占位符分別是 %u 、 %lu 和 %llu 。這樣不利于程序的可移植性。? ? C 語?提供了?個解決?法,創造了?個類型別名 size_t ,?來統?表? sizeof 的返回值類型。對應當前系統的 sizeof 的返回值類型,可能是 unsigned int ,也可能是unsigned long long ,總之是正整數。?
?VS2022 X64配置下的輸出:
? ? 在c語言的標準中規定,long類型長度大于等于int類型的長度,在不同的編譯器和系統環境下,他們的具體字節數會有所不同。
sizeof 在代碼進?編譯的時候,就根據表達式的類型確定了,?表達式的執?卻要在程序運?期間才能執?,在編譯期間已經將sizeof處理掉了,所以在運?期間就不會執?表達式了。
?1.6?signed 和 unsigned
?
? ? C 語?使? signed 和 unsigned 關鍵字修飾字符型和整型類型的? ? signed 關鍵字,表??個類型帶有正負號,包含正整數和負整數;? ? unsigned 關鍵字,表?該類型不帶有正負號,只能表?零和正整數? ? 對于 int 類型,默認是帶有正負號的,也就是說 int 等同于 signed int?? ? char 類型默認是否帶有正負號,由當前系統決定,這就是說,char 不等同于 signed char ,它有可能是 signed char ,也有可能是unsigned char 。
int main()
{signed int; //等價于int,int寫不寫都無所謂return 0;
}
1.7 數據類型的取值范圍
? ? 其實每?種數據類型有??的取值范圍,也就是存儲的數值的最?值和最?值的區間,有了豐富的類 型,我們就可以在適當的場景下去選擇適合的類型。如果要查看當前系統上不同數據類型的極限值:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? limits.h ?件中說明了整型類型的取值范圍。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? float.h 這個頭?件中說明浮點型類型的取值范圍
? ? ?有整型和字符型的取值范圍,因為字符最后在內存中會轉換為對應的十進制碼值,所以也是特殊的整型。
? ? ?0x開頭的是16進制的數,十六進制中10到15對應了英文字母的a - f,i64是說明這個數是個64位整型常量,就是說他的二進制的有效位數是63位,剩余的一位是他的符號位(后續講整型在內存中的存儲會深入講解,現在只是提一下)。
? ? ?宏定義是 C 語言中的一種預處理機制,它可以用一個標識符(宏名)來替換一段文本內容,常用于定義常量、代碼片段等,比如在
limits.h
頭文件中就用宏定義來表示各數據類型的取值邊界,后期會深入講解? ? ?其實數據類型取值范圍出現的意義就在于可以靈活運用不同的數據類型去表述不同的數值,假如一個數超出了int類型的最大范圍,那我們就可以考慮用long類型去存儲。
?二、變量
2.1 變量的創建
了解清楚了類型,我們使?類型做什么呢?類型是?來創建變量的。什么是變量呢?C語?中把經常變化的值稱為變量,不變的值稱為常量
變量創建的語法格式
data_type name;| || |
數據類型 變量名//舉例--未初始化的變量
int age; //整型變量
char ch; //字符變量
double weight; //浮點型變量//初始化后的變量
int age = 18;
char ch = 'w';
double weight = 48.0;
unsigned int height = 100
2.2 變量的分類
全局變量:不在大括號內部定義的變量,就是不在任何函數中定義的變量全局變量的使?范圍更?,在整個程序或模塊中都能被訪問和使用局部變量:在?括號內部定義的變量就是局部變量局部變量的使?范圍是?較局限,只能在??所在的局部范圍內使?的
int b = 0;//全局變量,整個工程中都可以使用int main()
{int a = 1;//局部變量,只能在main函數內部直接使用,注意是“直接”,在別的代碼塊也可以通過特殊方法使用,不過我們先不介紹,后續會進行介紹if(a){int b = 0;//局部變量,只能在{}中使用,出了{}就會被銷毀}return 0;
}
有沒有發現我定義了兩個名字相同的變量,那么如果要在if語句中使用這個變量,會使用局部定義的還是全局定義的那,局部優先,當局部變量和全局變量同名的時候,局部變量優先使?
2.3 變量的作用域和生命周期
作?域(scope)是程序設計概念,通常來說,?段程序代碼中所?到的名字并不總是有效(可?)的,?限定這個名字的可?性的代碼范圍就是這個名字的作?域。1. 局部變量的作?域是變量所在的局部范圍。2. 全局變量的作?域是整個?程(項?)。?命周期指的是變量的創建(申請內存)到變量的銷毀(收回內存)之間的?個時間段。1. 局部變量的?命周期是:進?作?域變量創建,?命周期開始,出作?域?命周期結束。2. 全局變量的?命周期是:整個程序的?命周期。
拓展知識?:全局變量和局部變量在內存中存儲在哪?呢?
?
? ? ?般我們在學習C/C++語?的時候,我們會關注? ? 內存中的三個區域:棧區、堆區、靜態區。? ? 1. 局部變量是放在內存的棧區? ? 2. 全局變量是放在內存的靜態區? ? 3. 堆區是?來動態內存管理的(后期會介紹)
其實內存區域的劃分會更加細致,以后在操作系統相關的文章會具體講解的
?三、操作符
3.1?算術操作符
C語?中為了?便運算,提供了?系列操作符,其中有?組操作符叫:算術操作符。分別是: +? -? *? /? % ,這些操作符都是雙?操作符(有兩個操作數)。注:操作符也被叫做:運算符,是不同的翻譯,意思是?樣的。
在介紹算術操作符前,我先補充一個知識點:強制類型轉換
//語法格式(類型)int a = 3.14;
//a的是int類型, 3.14是double類型,兩邊的類型不?致,編譯器會報警告int a = (int)3.14;
//意思是將3.14強制類型轉換為int類型,這種強制類型轉換只取整數部俗話說,強扭的?不甜,我們使?強制類型轉換都是萬不得已的時候使?,如果不需要強制類型轉化
就能實現代碼,這樣?然更好的。
下面是我演示的算術操作符的使用:?
?3.2 賦值操作符:=
//在變量創建的時候給?個初始值叫初始化,在變量創建好后,再給?個值,這叫賦值int main(
{int a = 0; //初始化a = 100; //賦值return 0;
}//賦值操作符也可以連續賦值int a = 3;
int b = 5;
int c = 0;
c = b = a+3;//連續賦值,從右向左依次賦值的。//C語言雖然支持連續賦值,但是顯然沒有下面的寫法好理解
int a = 3;
int b = 5;
int c = 0;
b = a+3;
c = b;
3.3 復合賦值符
//在寫代碼時,我們經常可能對?個數進??增、?減的操作int a = 10;
a = a+3;
a = a-2;//C語言提供了更簡便的方法:對應了上面的代碼
int a = 10;
a += 3;
a -= 2;//這樣的操作符都有下面這些:
+= -=
*= /= %=//下?的操作符后期講解
>>= <<=
&= |= ^=
剛開始這樣寫很不習慣,覺得代碼可讀性不好,以后你寫習慣了就會發現這樣寫挺香的......
?3.4 自增、自減操作符
前?介紹的操作符都是雙?操作符,有2個操作數的。C語?中還有?些操作符只有?個操作數,被稱為單?操作符。 ++、--、+(正)、-(負) 就是單?操作符的
?
//前置++ : 先+1,后使?int a = 10; int b = ++a;//++的操作數是a,是放在a的前?的,就是前置++ printf("a=%d b=%d\n",a , b); //11 11//和下面的代碼效果一樣 int a = 10; a = a+1; b = a; printf("a=%d b=%d\n",a , b);//后置++ : 先使?,后+1int a = 10; int b = a++;//++的操作數是a,是放在a的后?的,就是后置++ printf("a=%d b=%d\n",a , b);//11 10//和下面的代碼效果一樣 int a = 10; int b = a; a = a+1; printf("a=%d b=%d\n",a , b);//前置-- : 先-1,后使?int a = 10; int b = --a;//--的操作數是a,是放在a的前?的,就是前置-- printf("a=%d b=%d\n",a , b);//輸出的結果是:9 9//后置-- : 先使?,后-1int a = 10; int b = a--;//--的操作數是a,是放在a的后?的,就是后置-- printf("a=%d b=%d\n",a , b);//輸出的結果是:9 10
?3.5 正負號:+ -
這?的+是正號,-是負號,都是單?操作符//運算符 + 對正負值沒有影響,是?個完全可以省略的運算符,但是寫了也不會報錯。 int a = +10; 等價于 int a = 10;//運算符 - ?來改變?個值的正負號,負數的前?加上 - 就會得到正數,正數的前?加上 - 會得到負 數。 int a = 10; int b = -a; int c = -10; printf("b=%d c=%d\n", b, c);//這?的b和c都是-10 int a = -10; int b = -a; printf("b=%d\n", b); //這?的b是10
四、 printf 和 scanf
4.1 printf
printf的作?是將參數?本輸出到屏幕。它名字??的 f 代表 format (格式化),表?可以定制輸出?本的格式。printf() 是在標準庫的頭?件 stdio.h 定義的。使?這個函數之前,必須在源碼?件頭部引?這個頭?件。printf() 不會在?尾?動添加換?符,運?結束后,光標就停留在輸出結束的地?,不會?動換?。![]()
4.1 占位符
所謂 “占位符”,就是這個位置可以?其他值代?int main() {printf("There are %d apples\n", 3);//輸出There are 3 apples并換行return 0; }//占位符的第?個字符?律為百分號 % ,第?個字符表?占位符的類型, %d 表?這 ?代?的值必須是?個整數//輸出?本??可以使?多個占位符。 int main() {printf("%s says it is %d o'clock\n", "lisi", 21);//lisi says it is 21 o'clockreturn 0; }//printf() 參數與占位符是??對應關系,如果有 n 個占位符, printf() 的參數就應該有 n + 1 個。如果參數個數少于對應的占位符, printf() 可能會輸出內存中的任意值在printf("%s says it is %d o'clock\n", "lisi", 21);中,一共有 3 個參數。第 1 個參數是"%s says it is %d o'clock\n",這是格式控制字符串,規定了輸出的格式;第 2 個參數是"lisi" ,對應格式控制符%s(用于輸出字符串);第 3 個參數是21,對應格式控制符%d(用于輸出十進制整數)
printf() 的占位符有許多種類,與C語?的數據類型相對應。下?按照字?順序,列出常?的占位 符,?便查找,具體含義在后?文章介紹。 ? %a :?六進制浮點數,字?輸出為?寫。 ? %A :?六進制浮點數,字?輸出為?寫。 ? %c :字符。 ? %d :?進制整數。// int ? %e :使?科學計數法的浮點數,指數部分的 e 為?寫。 ? %E :使?科學計數法的浮點數,指數部分的 E 為?寫。 ? %i :整數,基本等同于 %d 。 ? %f :?數(包含 float 類型和 double 類型)。//float %f double - %lf ? %g :6個有效數字的浮點數。整數部分?旦超過6位,就會?動轉為科學計數法,指數部分的 e 為?寫。 ? %G :等同于 %g ,唯?的區別是指數部分的 E 為?寫。 ? %hd :?進制 short int 類型。 ? %ho :?進制 short int 類型。 ? %hx :?六進制 short int 類型。 ? %hu :unsigned short int 類型。 ? %ld :?進制 long int 類型。 ? %lo :?進制 long int 類型。 ? %lx :?六進制 long int 類型。 ? %lu :unsigned long int 類型。 ? %lld :?進制 long long int 類型。 ? %llo :?進制 long long int 類型。 ? %llx :?六進制 long long int 類型。 ? %llu :unsigned long long int 類型。 ? %Le :科學計數法表?的 long double 類型浮點數。 ? %Lf :long double 類型浮點數。 ? %n :已輸出的字符串數量。該占位符本?不輸出,只將值存儲在指定變量之中。 ? %o :?進制整數。 ? %p :指針(?來打印地址)。 ? %s :字符串。 ? %u :?符號整數(unsigned int)。 ? %x :?六進制整數。 ? %zd : size_t 類型。 ? %% :輸出?個百分號。
// 限定寬度--%5d--表?這個占位符的寬度?少為5位。如果不滿5位,對應的值的前?會添加空格。輸出的值默認是右對?,如果希望改成左對?,在輸出內容后?添加空格,可以在占位符的 % 的后?插 ??個 - 號。printf("限定寬度示例:\n");printf("%5d\n", 123); // 輸出為" 123"printf("%-5d\n", 123); // 輸出為"123 "printf("%12f\n", 123.45); // 輸出帶有默認精度且頭部補空格// 總是顯示正負號printf("\n總是顯示正負號示例:\n");printf("%+d\n", 12); // 輸出 +12printf("%+d\n", -12); // 輸出 -12// 限定小數位數printf("\n限定小數位數示例:\n");printf("Number is %.2f\n", 0.5); // 輸出 Number is 0.50printf("%6.2f\n", 0.5); // 輸出帶寬度限制和小數位數限制的結果--_ _0.50 我這塊_代表一個空格// 使用*代替限定值printf("\n使用*代替限定值示例:\n");printf("%.*f\n", 6, 2, 0.5); // 等同于printf("%6.2f", 0.5);// 輸出部分字符串printf("\n輸出部分字符串示例:\n");printf("%.5s\n", "hello world"); // 輸出 hello
4.3 scanf
基本運用? ?scanf?用于讀取鍵盤輸入,原型在 stdio.h 頭文件。格式字符串含占位符,像%d讀整數,%d讀浮點數。變量前要加&取地址符(指針變量除外)
也可一次讀多個變量,scanf("%d%f", &a, &b);
?,且會自動略過空白字符。返回值含義
? ? 其返回成功讀取的變量個數,失敗或無讀取返回?
0
?,遇錯誤或文件結束返回?EOF
?(值為?-1
?)。?
?
占位符
? ? 常用占位符有?
%c
?讀字符、%d
?讀整數 、%s
?讀字符串等。%c
?不略空白,%s
?遇空白停讀。讀字符串為防溢出,可限定長度,如?scanf("%5s", str);
?賦值忽略符
? *
?是賦值忽略符,加在占位符?%
?后,對應輸入不賦值給變量。
來兩個簡單的習題練練手:被5整除問題_牛客題霸_牛客網判斷兩個數的大小關系_牛客題霸_牛客網
?