【云小課】EI第29課 大數據時代的隱私利器-GaussDB(DWS)數據脫敏
2801
2025-03-31
本文是C語言的基礎知識,主要講解輸入、輸出以及運算符。
輸入—處理—輸出:這就是程序
輸入輸出(Input and Output, IO)是用戶和程序"交流"的過程。在控制臺程序中:
輸出一般是指將數據(包括數字、字符等)顯示在屏幕上。
輸入一般是指獲取用戶在鍵盤上輸入的數據。
在C語言程序中,幾乎沒有一個程序不需要這兩個函數,尤其是輸出函數(printf)。所以這兩個函數必須要掌握。
而如果在程序中要使用printf()或者scanf(),那么就必須要包含頭文件stdio.h。因為這兩個函數就是包含在該頭文件中的。我們在前面講編程時輸入的框架中就有"#include
輸出
在C語言中,有三個函數可以用來在顯示器上輸出數據,它們分別是:
puts():是 output string 的縮寫,意思是"輸出字符串"。只能輸出字符串,并且輸出結束后會自動換行。
putchar():函數每次只能輸出一個字符,輸出多個字符需要調用多次。
printf():可以輸出各種類型的數據。今天咱們就重點了解這個。
printf() 是最靈活、最復雜、最常用的輸出函數,完全可以替代puts()和 putchar(),大家一定要掌握。 注意 printf()函數只能在控制臺程序中使用,在Windows系統中,有窗口界面的程序無法通過printf()函數在窗口中顯示數據。
輸出控制符
常用的輸出控制符主要有以下幾個:
1)%d:按十進制整型數據的實際長度輸出。
2)%ld:輸出長整型數據。
3)%md: m為指定的輸出字段的寬度。如果數據的位數小于m,則左端補以空格,若大于m,則按實際位數輸出。
4)%u:輸出無符號整型(unsigned)。輸出無符號整型時也可以用%d,這時是將無符號轉換成有符號數,然后輸出。但編程的時候最好不要這么寫,因為這樣要進行一次轉換,使CPU多做一次無用功。
5)%c:用來輸出一個字符。
6)%f:用來輸出實數,包括單精度和雙精度,以小數形式輸出。不指定字段寬度,由系統自動指定,整數部分全部輸出,小數部分輸出6位,超過6位的四舍五入。
7)%.mf:輸出實數時小數點后保留m位,注意m前面有個點。
8)%o:以八進制整數形式輸出,這個就用得很少了,了解一下就行了。
9)%s:用來輸出字符串。用%s輸出字符串同前面直接輸出字符串是一樣的。但是此時要先定義字符數組或字符指針存儲或指向字符串,這個稍后再講。
10)%x(或%X或%#x或%#X)︰以十六進制形式輸出整數,這個很重要。
printf()用法
printf()格式控制符的完整形式如下:
%[flag][width][.precision]type
1)[] 表示此處的內容可有可無,是可以省略的。
2)type 表示輸出類型,比如 %d、%f、%c、%lf,type 就分別對應 d、f、c、lf,type 這一項必須有,這意味著輸出時必須要知道是什么類型。
3)width 表示輸出最小寬度,也就是至少占用幾個字符的位置;例如,%-9d中 width 對應9,表示輸出結果最少占用9個字符的寬度。當輸出結果的寬度不足width時,以空格補齊(如果沒有指定對齊方式,默認會在左邊補齊空格);當輸出結果的寬度超過 width 時,width不再起作用,按照數據本身的寬度來輸出。
4)flag 表示標志字符。例如,%-9d中 flag 對應-。
5).precision 表示精度,精度對于實數來說,表示小數位數。%.0f表示保留 0 位小數
下面咱來搞幾個例子更好的理解printf()的用法
1、輸出一個 4×4 的整數矩陣。
#include?
int?main()
{
int?a1=2021,?a2=666,?a3=520,?a4=1314;
int?b1=6666,?b2=7777,?b3=8888,?b4=9999;
int?c1=2021,?c2=07,?c3=14,?c4=1544;
int?d1=29,?d2=57,?d3=33,?d4=285747;
printf("%-9d?%-9d?%-9d?%-9d\n",?a1,?a2,?a3,?a4);
printf("%-9d?%-9d?%-9d?%-9d\n",?b1,?b2,?b3,?b4);
printf("%-9d?%-9d?%-9d?%-9d\n",?c1,?c2,?c3,?c4);
printf("%-9d?%-9d?%-9d?%-9d\n",?d1,?d2,?d3,?d4);
return?0;
}
運行結果:
2021??????666???????520???????1314
6666??????7777??????8888??????9999
2021??????7?????????14????????1544
29????????57????????33????????285747
輸出結果說明:
%-9d中,d表示以十進制輸出,9表示最少占9個字符的寬度,寬度不足以空格補齊,-表示左對齊。綜合起來,%-9d表示以十進制輸出,左對齊,寬度最小為9個字符。
2、width 的用法。
#include?
int?main()
{
int?e1=2021,?e2=666,?e3=520,?e4=1314;
int?f1=6666666,?f2=7777,?f3=888888,?f4=9999;
printf("%-4d?%-4d?%-4d?%-4d\n",?e1,?e2,?e3,?e4);
printf("%-4d?%-4d?%-4d?%-4d\n",?f1,?f2,?f3,?f4);
return?0;
}
運行結果:
2021?666??520??1314
6666666?7777?888888?9999
輸出結果說明:
指定輸出寬度為4,6666666和888888的寬度6,超過了 4,所以指定輸出寬度不再起作用,而是按照f1和f3的實際寬度輸出。
3、%x、%X、%#x、%#X的區別
#include?
int?main()
{
int?i?=?42;
printf("%x?|%X?|%#x?|%#X?",?i,?i,?i,?i);
return?0;
}
運行結果:
2a?|2A?|0x2a?|0X2A
輸出結果說明:
如果是小寫的x,輸出的字母就是小寫的;
如果是大寫的X,輸出的字母就是大寫的;
如果加一個"#",就以標準的十六進制形式輸出。
最好是加一個"#",否則如果輸出的十六進制數正好沒有字母的話會誤認為是一個十進制數呢!總之,不加"#"容易造成誤解。但是如果輸出0x2a或0x2a,那么人家一看就知道是十六進制。而且%#x和%#X中,筆者覺得大寫的比較好,因為大寫是絕對標準的十六進制寫法。所以在輸出十六進制的時候使用"%#X"比較好。
標志字符
flag 是標志字符。例如,%#X中 flag 對應 #,%-9d中 flags 對應-。printf()可以用的 flag有下面幾個:
1)-:表示左對齊。如果沒有,就按照默認的對齊方式,默認一般為右對齊。
2)+:用于整數或者小數,表示輸出符號(正負號)。如果沒有,那么只有負數才會輸出符號。
3)空格:用于整數或者小數,輸出值為正時冠以空格,為負時冠以負號。
4)#:
對于八進制(%o)和十六進制(%x/%X)整數,#表示在輸出時添加前綴;八進制的前綴是0,十六進制的前綴是 0x/0X。
對于小數(%f/%e/%g),#表示強迫輸出小數點。如果沒有小數部分,默認是不輸出小數點的,加上 #以后,即使沒有小數部分也會帶上小數點。
舉個栗子熟悉一下標志字符
#include?
int?main(){
int?m?=?422,?n?=?-1009;
float?f?=?520.1314;
printf("m=%6d,?m=%-6d\n",?m,?m);??//演示-的用法
printf("m=%+d,?n=%+d\n",?m,?n);??//演示+的用法
printf("m=%?d,?n=%?d\n",?m,?n);??//演示空格的用法
printf("f=%.0f,?f=%#.0f\n",?f,?f);??//演示#的用法
return?0;
}
運行結果:
m=???422,?m=422
m=+422,?n=-1009
m=?422,?n=-1009
f=520,?f=520.
輸出結果說明:
當以%6d輸出 m 時,是右對齊,所以在422前面補3個空格;當以%-6d輸出 m 時,是左對齊,所以在422后面補3個空格。
m 是正數,以%+d輸出時要帶上正號;n 是負數,以%+d輸出時要帶上負號。
m 是正數,以% d輸出時要在前面加空格;n 是負數,以% d輸出時要在前面加負號。
%.0f表示保留 0 位小數,也就是只輸出整數部分,不輸出小數部分。默認情況下,這種輸出形式是不帶小數點的,但是如果有了#標志,那么就要在整數的后面"硬加上"一個小數點,以和純整數區分開。
printf()不能立即輸出的問題
先看栗子
#include
#include
int?main()
{
printf("帥次真的帥嗎:");
sleep(5);??//程序暫停5秒鐘
printf("上下五千年的帥");
return?0;
}
這段代碼使用了兩個 printf() 語句,它們之間有一個 sleep() 函數,該函數的作用是讓程序暫停 5 秒,然后再繼續執行。sleep() 是 Linux 和 Mac OS 下特有的函數,不能用于 Windows。當然,Windows 下也有功能相同的暫停函數,叫做 Sleep()。
運行該程序,會發現第一個 printf() 并沒有立即輸出,而是等待 5 秒以后,和第二個 printf() 一起輸出了。
有種情況在第一個 printf() 的最后添加一個換行符,如下所示:
printf("帥次真的帥嗎\n");
效果就是編譯并運行程序,發現第一個 printf() 首先輸出(程序運行后立即輸出),等待 5 秒以后,第二個 printf() 才輸出。目的一下達到了。
因為我用的是Windows版在線編譯,所以兩種情況都是等待5秒一起輸出。這個你們可以親測一下。
為什么不能立即輸出?
這一切都是輸出緩沖區(緩存)在作怪!從本質上講,printf() 執行結束以后數據并沒有直接輸出到顯示器上,而是放入了緩沖區,直到遇見換行符"\n"才將緩沖區中的數據輸出到顯示器上。
輸出小結
1)轉換說明符在某些系統中對大小寫敏感,請注意不同系統的要求。如%f不能寫成%F。
2)格式控制字符串中,可以有轉義字符,如"\n"、"\b"、"\xab"等。
3)格式符以%開頭,以格式轉換符結束,中間有一些修飾作用的其他字符。
4)輸出字符"%"時,可以用連續的兩個%。
5)不同系統中實現格式輸出時,輸出結果的精度可能有差別。
6)printf()函數由于要解析格式控制字符串,比較耗費資源。如果是打印一個字符,可以用putchar()函數;如果僅僅是簡單地打印字符串,可以用puts()函數。
7)對于printf()函數的輸出表列中的求值順序,不同的編譯系統不一定相同,可以從左到右,也可從右到左。LCC編譯系統就是從左到右,而TC是從右到左。
對于初學者的咱們來說,上面講到的 printf() 用法已經比較復雜了,基本滿足了實際開發的需求,相信大家也需要一段時間才能熟悉。受到所學知識的限制,本文也未能講解 printf() 的所有功能,后續咱們還能不能深入,就看自己的了。
輸入
在C語言中,有多個函數可以從鍵盤獲得用戶輸入:
scanf():和 printf() 類似,scanf() 可以輸入多種類型的數據。
getchar()、getche()、getch():這三個函數都用于輸入單個字符。
gets():獲取一行數據,并作為字符串處理。
scanf()是最靈活、最復雜、最常用的輸入函數,但它不能完全取代其他函數。
scanf()函數
scanf 是 scan format 的縮寫,意思是格式化掃描,也就是從鍵盤獲得用戶輸入,和 printf 的功能正好相反。scanf的功能用一句話來概括就是通過鍵盤給程序中的變量賦值。
下面面咱們先看一個栗子:
#include?
int?main()
{
int?a?=?0,?b?=?0,?c?=?0,?d?=?0;
scanf("%d",?&a);??//輸入整數并賦值給變量a
scanf("%d",?&b);??//輸入整數并賦值給變量b
printf("a+b=%d\n",?a+b);??//計算a+b的值并輸出
scanf("%d?%d",?&c,?&d);??//輸入兩個整數并分別賦值給c、d
printf("c*d=%d\n",?c*d);??//計算c*d的值并輸出
return?0;
}
輸入:
輸入一個整數按回車連續四次;
將四個變量的值一次性輸入:27 30 18 10
運行結果:
a+b=57
c*d=180
輸出結果說明:
輸入一個整數按回車:從鍵盤輸入27,按下回車鍵,scanf() 就會讀取輸入數據并賦值給變量 a;本次輸入結束,接著執行下一個 scanf() 函數,再從鍵盤30,按下回車鍵,就會將30賦值給變量 b,都是同樣的道理。
四個變量的值一次性輸入:27 30 18 10按回車。
為什么這兩種方式都行呢?聯系輸入賦值有誤嗎?
從本質上講,我們從鍵盤輸入的數據并沒有直接交給 scanf(),而是放入了緩沖區中,直到我們按下回車鍵,scanf() 才到緩沖區中讀取數據。
如果緩沖區中的數據符合scanf()的要求,那么就讀取結束;
如果不符合要求,那么就繼續等待用戶輸入,或者干脆讀取失敗。
其實 scanf 和 printf 非常相似,只是功能相反罷了:
scanf("%d?%d",?&a,?&b);??//?獲取用戶輸入的兩個整數,分別賦值給變量?a?和?b
printf("%d?%d",?a,?b);??//?將變量?a?和?b?的值在顯示器上輸出
它們都有格式控制字符串,都有變量列表。不同的是,scanf 的變量前要帶一個&符號。&稱為取地址符,也就是獲取變量在內存中的地址。
數據是以二進制的形式保存在內存中的,字節(Byte)是最小的可操作單位。為了便于管理,我們給每個字節分配了一個編號,使用該字節時,只要知道編號就可以。
下圖是4G內存中每個字節的編號(以十六進制表示):
這個編號,就叫做地址(Address)。int a;會在內存中分配四個字節的空間,我們將第一個字節的地址稱為變量 a 的地址,也就是&a的值。對于前面講到的整數、浮點數、字符,都要使用 & 獲取它們的地址,scanf 會根據地址把讀取到的數據寫入內存。
下面咱輸出一下他們的地址:
#include?
int?main()
{
int?a=7;
int?b=15;
printf("&a=%p,?&b=%p\n",?&a,?&b);
return?0;
}
運行結果:
&a=0x7fffc349f32c,?&b=0x7fffc349f328
輸出結果說明:
這里看到的地址都是假的,是虛擬地址,并不等于數據在物理內存中的地址。虛擬地址是現代計算機因內存管理的需要才提出的概念。
輸入其它數據
除了輸入整數,scanf() 還可以輸入單個字符、字符串、小數等。 下面咱們先看個栗子:
#include?
int?main()
{
char?name[10];
int?age;
float?money;
scanf("%s",?&name);
scanf("%d",?&age);
scanf("%f",?&money);
printf("我叫:%s,今年?%d,兜里有%g刀。\n",?name,?age,?money);
return?0;
}
輸入內容:
SC?18?88.2
運行結果:
我叫:SC,今年?18,兜里有88.2刀。
輸出結果說明:
scanf() 和 printf() 雖然功能相反,但是格式控制符是一樣的,字符串、整數、小數對應的格式控制符分別是 %s、%d、%f。
字符串,在[]里面要指明字符串的最大長度。
運算符
運算符是一種告訴編譯器執行特定的數學或邏輯操作的符號。
算術運算符
下表顯示了 C 語言支持的所有算術運算符。假設變量 a的值為 10,變量 b 的值為 5,則:
下面咱跑個實例,了解一下算術運算符:
#include?
int?main()
{
int?a?=?10;
int?b?=?5;
int?c?;
c?=?a?+?b;
printf("1?-?c?的值是?%d\n",?c?);
c?=?a?-?b;
printf("2?-?c?的值是?%d\n",?c?);
c?=?a?*?b;
printf("3?-?c?的值是?%d\n",?c?);
c?=?a?/?b;
printf("4?-?c?的值是?%d\n",?c?);
c?=?a?%?b;
printf("5?-?c?的值是?%d\n",?c?);
c?=?a++;??//?賦值后再加?1?,c?為?10,a?為?11
printf("6?-?c?的值是?%d?a?的值是?%d\n",?c?,?a?);
c?=?a--;??//?賦值后再減?1?,c?為?11?,a?為?10
printf("7?-?c?的值是?%d?a?的值是?%d\n",?c?,?a?);
}
運行結果:
1?-?c?的值是?15
2?-?c?的值是?5
3?-?c?的值是?50
4?-?c?的值是?2
5?-?c?的值是?0
6?-?c?的值是?10?a?的值是?11
7?-?c?的值是?11?a?的值是?10
關系運算符
下表顯示了 C 語言支持的所有關系運算符。假設變量 a 的值為 10,變量 b 的值5,則:
下面咱跑個實例,了解一下關系運算符:
#include?
int?main()
{
int?a?=?10;
int?b?=?5;
if(?a?==?b?)
{
printf("1?-?a?等于?b\n"?);
}
else
{
printf("1?-?a?不等于?b\n"?);
}
if?(?a?
{
printf("2?-?a?小于?b\n"?);
}
else
{
printf("2?-?a?不小于?b\n"?);
}
if?(?a?>?b?)
{
printf("3?-?a?大于?b\n"?);
}
else
{
printf("3?-?a?不大于?b\n"?);
}
if?(?a?<=?b?)
{
printf("4?-?a?小于或等于?b\n"?);
}
if?(?a?>=?b?)
{
printf("5?-?a大于或等于?b\n"?);
}
}
運行結果:
1?-?a?不等于?b
2?-?a?不小于?b
3?-?a?大于?b
5?-?a大于或等于?b
邏輯運算符
下表顯示了 C 語言支持的所有關系邏輯運算符。假設變量 a 的值為 1,變量 b 的值為 0,則:
下面咱跑個實例,了解一下邏輯運算符:
#include?
int?main()
{
int?a?=?5;
int?b?=?20;
int?c?;
if?(?a?&&?b?)
{
printf("1?-?條件為真\n"?);
}
if?(?a?||?b?)
{
printf("2?-?條件為真\n"?);
}
/*?改變?a?和?b?的值?*/
a?=?0;
b?=?10;
if?(?a?&&?b?)
{
printf("3?-?條件為真\n"?);
}
else
{
printf("3?-?條件為假\n"?);
}
if?(?!(a?&&?b)?)
{
printf("4?-?條件為真\n"?);
}
}
運行結果:
1?-?條件為真
2?-?條件為真
3?-?條件為假
4?-?條件為真
位運算符
下表顯示了 C 語言支持的位運算符。假設變量 a 的值為 60,變量 b 的值為 13,則:
下面咱跑個實例,了解一下位運算符:
#include?
int?main()
{
unsigned?int?a?=?60;????//?60?=?0011?1100
unsigned?int?b?=?13;????//?13?=?0000?1101
int?c?=?0;
c?=?a?&?b;//12?=?0000?1100
printf("1?-?c?的值是?%d\n",?c?);
c?=?a?|?b;//61?=?0011?1101
printf("2?-?c?的值是?%d\n",?c?);
c?=?a?^?b;//49?=?0011?0001
printf("3?-?c?的值是?%d\n",?c?);
c?=?~a;//-61?=?1100?0011
printf("4?-?c?的值是?%d\n",?c?);
c?=?a?<2;?//40?=?1111?0000
printf("5?-?c?的值是?%d\n",?c?);
c?=?a?>>?2;//15?=?0000?1111
printf("6?-?c?的值是?%d\n",?c?);
}
運行結果:
1?-?c?的值是?12
2?-?c?的值是?61
3?-?c?的值是?49
4?-?c?的值是?-61
5?-?c?的值是?240
6?-?c?的值是?15
賦值運算符
下表列出了 C 語言支持的賦值運算符:
下面咱跑個實例,了解一下賦值運算符:
#include?
int?main()
{
int?a?=?21;
int?c?;
c?=??a;
printf("1?-?=??運算符實例,c?的值?=?%d\n",?c?);
c?+=??a;
printf("2?-?+=?運算符實例,c?的值?=?%d\n",?c?);
c?-=??a;
printf("3?-?-=?運算符實例,c?的值?=?%d\n",?c?);
c?*=??a;
printf("4?-?*=?運算符實例,c?的值?=?%d\n",?c?);
c?/=??a;
printf("5?-?/=?運算符實例,c?的值?=?%d\n",?c?);
c??=?200;
c?%=??a;
printf("6?-?%%=?運算符實例,c?的值?=?%d\n",?c?);
c?<<=??2;
printf("7?-?<<=?運算符實例,c?的值?=?%d\n",?c?);
c?>>=??2;
printf("8?-?>>=?運算符實例,c?的值?=?%d\n",?c?);
c?&=??2;
printf("9?-?&=?運算符實例,c?的值?=?%d\n",?c?);
c?^=??2;
printf("10?-?^=?運算符實例,c?的值?=?%d\n",?c?);
c?|=??2;
printf("11?-?|=?運算符實例,c?的值?=?%d\n",?c?);
}
運行結果:
1?-?=??運算符實例,c?的值?=?21
2?-?+=?運算符實例,c?的值?=?42
3?-?-=?運算符實例,c?的值?=?21
4?-?*=?運算符實例,c?的值?=?441
5?-?/=?運算符實例,c?的值?=?21
6?-?%=?運算符實例,c?的值?=?11
7?-?<<=?運算符實例,c?的值?=?44
8?-?>>=?運算符實例,c?的值?=?11
9?-?&=?運算符實例,c?的值?=?2
10?-?^=?運算符實例,c?的值?=?0
11?-?|=?運算符實例,c?的值?=?2
雜項運算符
下表列出了 C 語言支持的其他一些重要的運算符,包括 sizeof 和 ? :
下面咱跑個實例,了解一下雜項運算符:
#include?
int?main()=
{
int?a?=?4;
short?b;
double?c;
int*?ptr;
/*?sizeof?運算符實例?*/
printf("1?-?變量?a?的大小?=?%lu\n",?sizeof(a)?);
printf("2?-?變量?b?的大小?=?%lu\n",?sizeof(b)?);
printf("3?-?變量?c?的大小?=?%lu\n",?sizeof(c)?);
/*?&?和?*?運算符實例?*/
ptr?=?&a;????/*?'ptr'?現在包含?'a'?的地址?*/
printf("4?-?a?的值是?%d\n",?a);
printf("5?-?*ptr?是?%d\n",?*ptr);
/*?三元運算符實例?*/
a?=?10;
b?=?(a?==?1)???20:?30;
printf("6?-?b?的值是?%d\n",?b?);
b?=?(a?==?10)???20:?30;
printf("7?-?b?的值是?%d\n",?b?);
}
運行結果:
1?-?變量?a?的大小?=?4
2?-?變量?b?的大小?=?2
3?-?變量?c?的大小?=?8
4?-?a?的值是?4
5?-?*ptr?是?4
6?-?b?的值是?30
7?-?b?的值是?20
如有錯誤,煩請斧正
C 語言 面向對象編程
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。