C語言基礎知識-數據類型
作者:尹正傑
版權聲明:原創作品,謝絕轉載!否則將追究法律責任。
一.常量與變量
1>.關鍵字
C的關鍵字共有32個。
1>.數據類型關鍵字(12個) char,short,int,long,float,double,unsigned,signed,struct,union,enum,viod
2>.控制語句關鍵字(12個)
if,else,switch,case,default,for,do,while,break,contiue,goto,return 3>.存儲類型關鍵字(5個)
auto,extern,register,static,const 4>.其他關鍵字(3個)
sizeof,typedef,volatile
2>.數據類型
數據類型的作用:編譯器預算對象(變量)分配的內存空間大小。
1>.數據類型的定義
變量的定義:
數據類型 變量名[也叫標識符],如:"char Habby;"
變量的賦值:
變量名 = 值,如:“NAME=Jason Yin;”
數據類型 變量名稱[標識符] = 值,如:"int AGE = 10;"
2>.標識符的命名規則
字母,數字,下划線組成;
不能以數字開頭(第一個字符必須為字母或下划線);
見名知意;
不能和同一函數內其他標識符重復;
不能使用C語言內置的關鍵字;
標識符中字母區分大小寫;
3>.常量
常量的作用: 在程序運行過程中,其值不能被改變的量; 常量一般出現在表達式或賦值語句中; 舉幾個例子: 整型常量 : 100,200,-100,0 等 實型常量 : 3.14,9.18,1.44 等 字符型常量 : 'a','b','10','\n' 字符串常量 : "age","123","jason" 常量的定義: const 數據類型 常量名; #deifne 常量名 值 注意: 通過“#deifne”定義的常量是根據值來匹配數據類型的,推薦使用這種方式定義常量。 const修飾的常量是不安全的,可以通過指針來修改
4>.變量
變量的作用:
在程序運行過程中,其值可以改變;
變量在使用前必須先定義,定義變量前必須有相應的數據類型;
變量特點:
變量在編譯時為其分配相應的內存空間;
可以通過其名稱和地址訪問相應內存;
5>.類型限定符
extenrn: 聲明一個變量,extern聲明的變量沒有建立存儲空間。 const: 定義一個常量,常量的值不能修改。例如 const int MONTH = 12; volatile: 防止編譯器優化代碼。 register: 定義寄存器變量,提高效率。register是建議型的指令,而不是命令型的指令,如果CPU有空閑寄存器,那么register就生效,如果沒有空閑寄存器,那么register無效。
6>.使用案例
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat variable_definitions.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> #define PI 3.1415926 int main(void) { //定義變量 int _age = 18; printf("Age={%d}\n",_age); //定義常量 const int MONTH = 12; printf("一年有{%d}個月\n",MONTH); //引用使用"#define"定義的變量 printf("圓周率為:{%f}\n",PI); } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o variable_definitions variable_definitions.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./variable_definitions Age={18} 一年有{12}個月 圓周率為:{3.141593} [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
二.進制
進制也就是進制位,是人們規定的一種進位方法。對於任何一種進制-X進制,就表示某一位置的數運算時逢x進一位。十進制是逢十進一,十六進制是逢十六進一,二進制就是逢二進一,依次類推,x進制就是逢x進位。
1>.二進制
二進制逢2進1,所有的數都是由0,1組成,如11+1=100。
十進制轉二進制:
除二反序取余法(將十進制數每次除以2,取出余數,按照結果倒敘排序)。
二進制專十進制:
權值法(將二進制各個位數從0位開始乘以2的N次冪,將各個位數的結果相加)。
當前計算機系統使用的基本上都是二進制系統,數據在計算機中主要以補碼的形式存儲。以下一些術語大家可以了解一下:
bit(比特)
一個二進制代表以為,一個位只能表示0或1兩種狀態。數據傳輸是習慣以“位”(bit)為單位。
Byte(字節)
一個字節為8個二進制,稱為8位,計算機中存儲的最小單位是字節。數據存儲是習慣以“字節”(Byte)為單位。
WORD(雙字節)
2個字節,即16位。
DWORD
兩個WORD,4個字節,即32位。
1b
1bit,1位。
1B
1Byte,1字節,8位。
1k,1K
1024B。
1M(1兆)
1024k,1024*1024。
1G
1024M。
1T
1024G。
1Kb(千位)
1024bit,1024位。
1Kb(千字節)
1024Byte,1024字節。
1Mb(兆位)
1024Kb = 1024 * 1024bit。
1MB(兆字節)
1024KB=1024 * 1024Byte
2>.八進制
八進制逢8進1,所有的數字是0到7組成。
十進制轉八進制:
除八反序取余法(將十進制數每次除以8,取出余數,按照結果倒敘排序)。
二進制轉化為八進制:
將二進制數字從右到左,每3個二進制數划分為一組,將每組數據的二進制轉換成八進制對應的數字即可。
八進制轉換為二進制:
八四二一法則(將八進制的每一個位數上的數字拆開,分別用二進制表示即可。)
3>.十進制
十進制逢10斤=1,有數字0-9組成,也是咱們生活中默認使用的進制。
十進制轉換成二進制,八進制,十六進制的方法我這里就不啰嗦了,過於簡單我這里就不啰嗦了,我這里重點說一下十進制的小數轉換成二進制的方式。
十進制小數轉換成二進制:
小數部分和2相乘,取整數,不足1取0,每次相乘都是小數部分,順序看取整后的數就是轉化后的結果。為了方便說明,我們看一下十進制的0.521如何用二進制表示:
0.521
* 2
---------
1.042 ---->第一次計算結果,取整數部分1,然后把小數部分0.042繼續和2相乘
0.042 ---->這里的0.042就是上面計算的1.042的小數部分
* 2
----------
0.084 ----->第二次計算結果,取整數部分0,然后把小數部分0.084機型和2相乘
0.084 ----->這里的0.084是上面計算的0.084的小數部分
* 2
----------
0.168 ------>第三次計算結果,取整數部分0,並終止計算,因為十進制0.521只有3位小數,顧我們只需要取3位二進制位即可,最終結果為0.100
如上所述,我們來總結一下十進制轉換成二進制的幾個要點:
(1)乘的時候只乘小數部分;
(2)0.521只有3位,因此我們只需要算出3位二進制位置即可;
(3)0.521的二進制數為:0.100
4>.十六進制
十六進制逢16進1,由數字0-9和字母A-F組成。 十進制轉化為十六進制 除十六反序取余法(將十進制數每次除以16,取出余數,按照結果倒敘排序,需要注意的是大於10的數字應該由A-F來表示) 十六進制轉化為十進制 權值法(將二進制各個位數從0位開始乘以16的N次冪,將各個位數的結果相加)。 十六進制轉換為二進制 八四二一法則(將十六進制的每一個位數上的數字拆開,分別用二進制表示即可。) 二進制轉換為十六進制 將二進制數字從右到左,每4個二進制數划分為一組,將每組數據的二進制轉換成八進制對應的數字即可。
十六進制轉換為八進制
思路就是先將十六進制轉換成二進制,再將二進制轉換成八進制。
八進制轉換成十六進制
思路就是先將八進制換轉成二進制,再將二進制轉換成十六進制。
5>.進制轉換表
6>.在C程序中進制打印案例
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main(void) { //十進制數字10 int a = 10; printf("%d\n",a); //定義八進制 int b = 010; printf("%d\n",b); //定義十六進制 int c = 0x10; printf("%d\n",c); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./binary_conversion 10 8 16 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main(void) { //十進制數字10 int a = 10; printf("%o\n",a); //定義八進制 int b = 010; printf("%o\n",b); //定義十六進制 int c = 0x10; printf("%o\n",c); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./binary_conversion 12 10 20 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main(void) { //十進制數字10 int a = 10; printf("%x\n",a); //定義八進制 int b = 010; printf("%x\n",b); //定義十六進制 int c = 0x10; printf("%x\n",c); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./binary_conversion a 8 10 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main(void) { //十進制數字10 int a = 10; printf("%X\n",a); //定義八進制 int b = 010; printf("%X\n",b); //定義十六進制 int c = 0x10; printf("%X\n",c); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./binary_conversion A 8 10 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
三.sizeof關鍵字
sizeof不是函數,所以不需要包含任何頭文件,它的功能是計算一個數據類型的大小,單位為字節;
sizeof的返回值為size_t; sizeof_t類型在32位操作系統下是unsigned int,是無符號的整數。
注意:下面結果是根據64位操作系統獲取的數據類型大小,此時案例可參考下面的“使用sizeof查看各個數據類型占用內存大小案例”
char(字符型,1Byte) < short(短整型,2Byte) < int(整型,4Byte)|float(單精度浮點型,4Byte)|long(長整型,4Byte) < long long(長長整型,8Byte)|double(雙精度浮點型,8Byte)

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat sizeof_demo.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main() { int a; int b=sizeof(a); //sizeof得到指定值占用內存大小,單位為字節. printf("b=%d\n",b); size_t c = sizeof(a); //用無符號的方式輸出c的值 printf("c=%u\n",c); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o sizeof_demo sizeof_demo.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./sizeof_demo b=4 c=4 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat sizeof_demo2.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main() { int a = 10; //sizeof()求出數據類型在內存占用字節(Byte)大小 int len1 = sizeof(a); printf("%d\n",a); printf("int = %d\n",len1); //單精度浮點型 float b = 3.14; int len2 = sizeof(b); printf("%d\n",b); printf("float = %d\n",len2); //字符型 char c = 'A'; int len3 = sizeof(c); printf("%d\n",c); printf("char = %d\n",len3); //雙精度浮點型 double d = 9.18; int len4 = sizeof(d); printf("%d\n",d); printf("double = %d\n",len4); //短整型 short e = 10; int len5 = sizeof(e); printf("%d\n",e); printf("short = %d\n",len5); //長整型 long f = 10; int len6 = sizeof(f); printf("%d\n",f); printf("long = %d\n",len6); //長長整型 long long g = 10; int len7 = sizeof(g); printf("%d\n",g); printf("long long = %d\n",len7); } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o sizeof_demo2 sizeof_demo2.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./sizeof_demo2 10 int = 4 2147483640 float = 4 65 char = 1 2147483639 double = 8 10 short = 2 10 long = 8 10 long long = 8 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
四.計算機內存數值存儲方式
1>.原碼
一個數的原碼(原始的二進制碼)有如下特點: 最高位作為符號位,0表示正,1表示負; 其它數值部分都是數值本身絕對值的二進制數; 負數的原碼是在其絕對值的基礎上,最高位變為1; 舉個例子,我們用一個字節的原碼來表示+15,-15,+0,-0 +15 : 0000 1111 -15 : 1000 1111 +0 : 0000 0000 -0 : 1000 0000 原碼表示方法簡單易懂,帶有符號數本身轉換方便,只要符號位還原即可,但當兩個整數相減或不同符號相加時,必須比較兩個數哪個絕對值大,才能決定誰減誰,才能確定結果是正還是負,所以原碼不便於加減運算。
2>.反碼
一個數的反碼(原始的二進制碼)有如下特點: 對於正數,反碼與原碼相同; 對於負數,符號位不變,其它部位去反; 舉個例子,我們用一個字節的反碼來表示+15,-15,+0,-0 +15 : 0000 1111 -15 : 1111 0000 +0 : 0000 0000 -0 : 1111 1111
反碼運算也不方便,通常用來作為求補碼的中間過渡
3>.補碼
在計算機中,數值一律用補碼來存儲。補碼特點如下: 對於正數,原碼,反碼,補碼相同; 對於負數,其補碼為它的反碼加1; 補碼符號位不動,其他為求反,最后整個數加1,得到原碼;
舉個例子,我們用一個字節的補碼來表示+15,-15,+0,-0
+15 : 0000 1111
-15 : 1111 0001
+0 : 0000 0000
-0 : 0000 0000
如果對補碼還迷糊的小伙伴,可參考博主推薦閱讀:https://www.cnblogs.com/yinzhengjie/p/8666354.html。

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat complement.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main() { int a = -15; printf("%x\n",a); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o complement complement.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./complement fffffff1 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# /* 如上所述,輸出結果為“fffffff1”,改值用途二進制表示為:1111 1111 1111 1111 1111 1111 1111 0001 符號位不變,其他去反,我們查看該二進制的反碼為:1000 0000 0000 0000 0000 0000 0000 1110 我們在反碼的基礎上加1,得到最終的補碼為:1000 0000 0000 0000 0000 0000 0000 1111,即最高位是符號位,1代表負數,即改值二進制的補碼表示的為-15. */
4>.補碼的意義
在計算機系統中,數值一律使用補碼來存儲,主要原因如下:
統一了0的編碼;
將符號位和其他位統一處理;
將減法運算轉變為加法運算;
兩個用補碼表示的數相加時,如果最高位(符號位)有進位,則進位被舍棄。
五.整型(int)
1>.整型變量的定義和輸出
%d 輸出一個有符號的10進制int類型 %o(字母o) 輸出8進制的int類型 %x 輸出16進制的int類型,字母以小寫輸出 %X 輸出16進制的int類型,字母以大寫輸出 %u 輸出一個10進制的無符號數

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat int_dome1.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main() { int a = 123; //定義變量a,以10進制方式賦值為123. int b = 0567; //定義變量b,以8進制方式賦值0567. int c = 0xabc; //定義變量c,以16進制方式賦值為0xabc. printf("a = %d\n",a); printf("8進制:b=%o\n",b); printf("10進制:b=%d\n",b); printf("16進制:c=%x\n",c); printf("16進制:c=%X\n",c); printf("16進制:c=%d\n",c); unsigned int d = 0xffffffff; //定義無符號int變量d,以16進制方式賦值 printf("有符號方式打印:d = %d\n",d); printf("無符號方式打印:d = %u\n",d); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o int_dome1 int_dome1.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./int_dome1 a = 123 8進制:b=567 10進制:b=375 16進制:c=abc 16進制:c=ABC 16進制:c=2748 有符號方式打印:d = -1 無符號方式打印:d = 4294967295 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
2>.整型變量的輸入
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat int_dome2.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main() { int num; printf("請輸入a的值:>>> "); //不要加換行符"\n" scanf("%d",&num); //打印輸入的int類型的值 printf("num = %d\n",num); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o int_dome2 int_dome2.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./int_dome2 請輸入a的值:>>> 20190520 num = 20190520 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
3>.short,int,long,long long
short(短整型) 2字節 int(整型) 4字節 long(長整型) windows為4字節,Linux為4自己(32位),8字節(64位) long long(長長整型) 8字節
溫馨提示:
整型數據在內存中占用的字節數與所選擇的操作系統有關。雖然C語言標准中沒有明確規定整型數據的長度,但long類型整型的長度不能短於int類型,short類型整數的長度長於int類型。
當一個小的數據類型賦值給一個大的數據類型,不會出錯,因為編譯器會自動轉化。但是當一個大的類型賦值給一個小的數據類型,那么就可能丟失高位。
以下是整型常量及其所需類型
10
代表int類型
10l,10L
代表long類型
10ll,10LL
代表long long類型
10u,10U
代表unsigned int類型
10ul,10UL
代表unsigned long類型
10ull,10ULL
代表unsigned long long類型
接下來我們查看一下打印格式及其含義
%d
輸出int類型
%l
輸出long類型
%ll
輸出long long類型
%hu
輸出unsigned short類型
%u
輸出unsigned int類型
%lu
輸出unsigned long類型
%llu
輸出unsigned long long類型

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat int_dome3.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main() { short a = 10; int b = 10; long c = 10L; long long d = 10LL; printf("sizeof(a) = %u\n",sizeof(a)); printf("sizeof(b) = %u\n",sizeof(b)); printf("sizeof(c) = %u\n",sizeof(c)); printf("sizeof(d) = %u\n",sizeof(d)); printf("short a = %hd\n",a); printf("int b = %d\n",b); printf("long c = %ld\n",c); printf("long long d = %lld\n",d); unsigned short a2 =20u; unsigned int b2 = 20u; unsigned long c2 = 20ul; unsigned long long d2 = 20ull; printf("unsigned short a = %hu\n",a2); printf("unsigned int b = %u\n",b2); printf("unsigned long c = %lu\n",c2); printf("unsigned long long d = %llu\n",d2); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o int_dome3 int_dome3.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./int_dome3 sizeof(a) = 2 sizeof(b) = 4 sizeof(c) = 8 sizeof(d) = 8 short a = 10 int b = 10 long c = 10 long long d = 10 unsigned short a = 20 unsigned int b = 20 unsigned long c = 20 unsigned long long d = 20 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
4>.有符號和無符號的區別
一個有符號的整型數據可以分為兩部分:一部分是符號位,一部分是數字位。 無符號數據類型只包含數字位部分。 當我們寫程序要處理一個不可能出現負數的時候,一般用無符號數,這樣可以增大數的表達最大值。
有符號和無符號整型取值范圍如下: short 占用2字節,取值范圍在-32768到32767(-2的15次方到2的15次方減1)。 int 占用4字節,取值范圍在-2147483648代2147483647(-2的31次方到2的31次方減1) long 占用4字節,取值范圍在-2147483648代2147483647(-2的31次方到2的31次方減1) unsigned short 占用2自己,取值范圍在0到65535(0到2的15次方減1) unsigned int 占用4字節,取值范圍在0到4294967295(0到2的32次方減1) unsigned long 占用4字節,取值范圍在0到4294967295(0到2的32次方減1)
六.字符型(char)
1>.字符變量的定義和輸出
字符型變量用於存儲一個單一字符,在C語言中用char表示,其中每個字符變量都會占用1個字節。在給字符型變量賦值時,需要用一對英文半角格式的單引號(' ')把字符括起來。 字符變量實際上並不是把該字符本身放到變量的內存單元中去,而是將該字符對應的ASCII編碼放到變量中的存儲單元中。char的本質就是一個1字節大小的整型。

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat char_demo.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main(void) { char ch = 'a'; printf("sizeof(ch) = %u\n",sizeof(ch)); printf("ch(%%c) = %c\n",ch); //輸出字符串 putchar(ch); //該方法只能輸出字符,該行及下面一行均是輸出字符 putchar('\n'); printf("ch(%%d) = %d\n",ch); //打印'a'對應的ASSCII的值 return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o char_demo char_demo.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./char_demo sizeof(ch) = 1 ch(%c) = a a ch(%d) = 97 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
2>.字符變量的輸入

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat char_demo2.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main(void) { char input; //scanf("%c",&input); //接收用戶輸入的一個字符 input = getchar(); //除了使用上面的scanf方法獲取用戶輸入,我們還可以用getchar來獲取用戶輸入的字符 putchar(input); //將用戶輸入的字符打印出來 putchar('\n'); //上面打印出來並沒有換行,我們可以人為的給它加一個換行符 return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o char_demo2 char_demo2.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./char_demo2 Y Y [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
3>.ASCII對照表
ASCII碼大致有以下兩部組成: ASCII非打印控制字符: ASCII表上的數字0-31分配了控制字符,用於控制像打印機等一些外圍設備。 ASCII打印字符 數字32-126分配了能在鍵盤上找到的字符,當查看或打印文檔時就會出現。數字127代表Del命令。
ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 |
---|---|---|---|---|---|---|---|
0 | NUT | 32 | (space) | 64 | @ | 96 | 、 |
1 | SOH | 33 | ! | 65 | A | 97 | a |
2 | STX | 34 | " | 66 | B | 98 | b |
3 | ETX | 35 | # | 67 | C | 99 | c |
4 | EOT | 36 | $ | 68 | D | 100 | d |
5 | ENQ | 37 | % | 69 | E | 101 | e |
6 | ACK | 38 | & | 70 | F | 102 | f |
7 | BEL | 39 | , | 71 | G | 103 | g |
8 | BS | 40 | ( | 72 | H | 104 | h |
9 | HT | 41 | ) | 73 | I | 105 | i |
10 | LF | 42 | * | 74 | J | 106 | j |
11 | VT | 43 | + | 75 | K | 107 | k |
12 | FF | 44 | , | 76 | L | 108 | l |
13 | CR | 45 | - | 77 | M | 109 | m |
14 | SO | 46 | . | 78 | N | 110 | n |
15 | SI | 47 | / | 79 | O | 111 | o |
16 | DLE | 48 | 0 | 80 | P | 112 | p |
17 | DCI | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 | 50 | 2 | 82 | R | 114 | r |
19 | DC3 | 51 | 3 | 83 | S | 115 | s |
20 | DC4 | 52 | 4 | 84 | T | 116 | t |
21 | NAK | 53 | 5 | 85 | U | 117 | u |
22 | SYN | 54 | 6 | 86 | V | 118 | v |
23 | TB | 55 | 7 | 87 | W | 119 | w |
24 | CAN | 56 | 8 | 88 | X | 120 | x |
25 | EM | 57 | 9 | 89 | Y | 121 | y |
26 | SUB | 58 | : | 90 | Z | 122 | z |
27 | ESC | 59 | ; | 91 | [ | 123 | { |
28 | FS | 60 | < | 92 | / | 124 | | |
29 | GS | 61 | = | 93 | ] | 125 | } |
30 | RS | 62 | > | 94 | ^ | 126 | ` |
31 | US | 63 | ? | 95 | _ | 127 | DEL |
NUL空 | VT 垂直制表 | SYN 空轉同步 |
---|---|---|
STX 正文開始 | CR 回車 | CAN 作廢 |
ETX 正文結束 | SO 移位輸出 | EM 紙盡 |
EOY 傳輸結束 | SI 移位輸入 | SUB 換置 |
ENQ 詢問字符 | DLE 空格 | ESC 換碼 |
ACK 承認 | DC1 設備控制1 | FS 文字分隔符 |
BEL 報警 | DC2 設備控制2 | GS 組分隔符 |
BS 退一格 | DC3 設備控制3 | RS 記錄分隔符 |
HT 橫向列表 | DC4 設備控制4 | US 單元分隔符 |
LF 換行 | NAK 否定 | DEL 刪除 |
4>.轉義字符
所有的轉義字符和所對應的意義:
轉義字符
|
意義
|
ASCII碼值(十進制)
|
\a
|
響鈴(BEL)
|
007
|
\b
|
退格(BS) ,將當前位置移到前一列
|
008
|
\f
|
換頁(FF),將當前位置移到下頁開頭
|
012
|
\n
|
換行(LF) ,將當前位置移到下一行開頭
|
010
|
\r
|
回車(CR) ,將當前位置移到本行開頭
|
013
|
\t
|
水平制表(HT) (跳到下一個TAB位置)
|
009
|
\v
|
垂直制表(VT)
|
011
|
\\
|
代表一個反斜線字符''\'
|
092
|
\'
|
代表一個單引號(撇號)字符
|
039
|
\"
|
代表一個雙引號字符
|
034
|
\? | 代表一個問號 | 063 |
\0
|
空字符(NUL)
|
000
|
\ddd
|
1到3位八進制數所代表的任意字符
|
三位八進制
|
\xhh
|
1到2位十六進制所代表的任意字符
|
十六進制
|
5>.數值溢出
當超過了一個數據類型能夠存放最大的范圍時,數值會溢出。 有符號最高位溢出的區別:符號位溢出會導致數的正負發生改變,但最高位的溢出會導致最高位丟失。 char 占用1字節 取值范圍在-128到127(負的2的7次方到2的7次方減1) unsigned char 占用1字節 取值范圍0到255(0到2的8次方-1)
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat char_demo3.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main(void) { char input; //符號位溢出會導致數的正負發生改變,0x7f(十六進制表示法)對應的二進制為:0111 1111,給其加2后為:1000 0001,這是負數的原碼,其補碼為:1111 1111,十進制為-127. input = 0x7f + 2; //127 + 2 printf("%d\n",input); //最高位的溢出會導致高位丟失,0xff(十六進制表示法)對應的二進制為:1111 1111,給其加1后變為:1 0000 0000,char只有8位最高位的溢出(有網友也喜歡說是高位截短),糾其原因是一個字節存取8個比特位,因此結果為:0000 0000,十進制為0. unsigned char input2; input2 = 0xff +1; //255+1 printf("%u\n",input2); //和上面案例原理相同,0xff(十六進制表示法)對應的二進制為:1111 1111,給其加2后變為:1 0000 0001,高位截斷后結果為:0000 0001,十進制為1. input2 = 0xff + 2; printf("%u\n",input2); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o char_demo3 char_demo3.c char_demo3.c: In function ‘main’: char_demo3.c:19:2: warning: large integer implicitly truncated to unsigned type [-Woverflow] #我們在編譯成可執行文件時,發現有warning的提示信息,說是無符號類型數據溢出(-Woverflow)啦,此消息咱們忽略即可,因為這個溢出是咱們人為造成溢出的~ input2 = 0xff +1; //255+1 ^ char_demo3.c:23:2: warning: large integer implicitly truncated to unsigned type [-Woverflow] input2 = 0xff + 2; ^ [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./char_demo3 -127 0 1 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
七.實型(浮點型)
實型變量也可以成為浮點型變量,浮點型變量是用來存儲小數數值的。在C語言中,浮點型變量分為兩種:單精度浮點數(float),雙精度浮點數(double),但是double型變量所表示的浮點數比float型變量更精確。
float:占用4字節,7位有效數字。
double:占用8字節,15~16位有效數字。
由於浮點型變量是由有限的存儲單元組成的,因此只能提供有限的有效數字。在有效位以外的數字將被舍去,這樣可能會產生一些誤差。
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat float_demo.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main(void) { float a = 3.14f; //或者3.14F,這是傳統賦值 double b = 3.14; printf("a = %f\n",a); printf("b = %f\n",b); a = 3.2e3f; //或者3.2E3f,科學法賦值,表示3.2 * 1000 = 3200 printf("a1 = %f\n",a); a = 100e-3f; //表達式為:100 * 0.001 = 0.1 printf("a2 = %f\n",a); a = 3.1415926f; printf("a3 = %f\n",a); //結果為3.141593,因為我們知道a是float類型,占用4字節,僅僅有7位有效數字,最后一位會進行四舍五入法得結果 float r = 2; float s = r * r * 3.14; printf("%.2f\n",s); //注意,“%.2f"表示保留小數點后2位. return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o float_demo float_demo.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./float_demo a = 3.140000 b = 3.140000 a1 = 3200.000000 a2 = 0.100000 a3 = 3.141593 12.56 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
八.字符串格式化輸入和輸出
1>.字符串常量
字符串是內存中一段連續的char空間,以'\0'(數字0)結尾。 字符串常量是由雙引號括起來的字符序列,如"chaina","C parogram","$PATH"等都是合法的字符串常量。 字符串常量與字符常量的不同:
每個字符串的結尾,編譯器會自動的添加一個結束標志位“\0”,即"a"包含兩個字符'a'和'\0'
2>.printf函數和putchar函數
printf是輸出一個字符串,putchar輸出一個char。 printf格式字符: 打印格式 對應數據類型 含義 %d int 接收整數值並將它表示為有符號的十進制整數 %hd short int 端整數 %hu unsigned short 無符號短整數 %o unsigned int 無符號8進制整數 %u unsigned int 無符號10進制整數 %x,%X unsigned int 無符號16進制整數,x對應的是abcdef,X對應的是ABCDEF %f float 單精度浮點數 %lf double 雙精度浮點型 %e,%E double 科學計數法表示的數,此處"e"的大小寫代表輸出時用"e"的大小寫 %c char 字符型,可以把輸入的數字按照ASCII對應轉換為對應的字符 %s char * 字符串,輸出字符串中的字符直至字符串的空字符(字符串以'\0'結尾,這個'\0'即空字符) %p void 以16進制形式輸出指針 %% % 輸出一個百分號,即"%" printf附加格式: 字符 含義 l(這個是小寫字母l) 附加在d,u,x,o前面,表示長整數 - 左對齊 m(代表一個整數) 數據最小寬度 0(這個是數字0) 將輸出的前面補上0知道滿指定列環位置不可用搭配使用- m.n(代表一個整數) m值域寬,即對應的輸出項在輸出設備上所占的字符數,n指進度,用戶說明輸出的實型數的小數位數。對數值型的來說,未指定n時,隱含的精度為n=6位。

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat echo.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main() { int a = 100; printf("a = %d\n",a); //格式化輸出一個字符串 printf("%p\n",&a); //輸出變量a在內存中的地址編碼 printf("%%d\n"); char c = 'a'; putchar(c); //putchar只有一個參數,就是要輸出的char long long a3 = 1000; printf("%lld,%llx,%llo\n",a3,a3,a3); int abc = 10; printf("abc = '%6d'\n",abc); printf("abc = '%-6d'\n",abc); printf("abc = '%0d'\n",abc); printf("abc = '%-06d'\n",abc); double d = 12.3; printf("d = \'%-10.3lf'\n",d); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o echo echo.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./echo a = 100 0x7fff18387bec %d a1000,3e8,1750 abc = ' 10' abc = '10 ' abc = '10' abc = '10 ' d = '12.300 ' [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#
3>.scanf函數與getchar函數
getchar是從標准輸入設備讀取一個char
scanf通過%轉義的方式可以得到用戶通過標准輸入設備輸入的數據

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat echo2.c /* @author :yinzhengjie blog:http://www.cnblogs.com/yinzhengjie EMAIL:y1053419035@qq.com */ #include <stdio.h> int main() { char ch1; char ch2; char ch3; int a; int b; printf("請輸入ch1的字符:>>> "); ch1 = getchar(); printf("ch1 = %c\n",ch1); getchar(); //測試此處getchar()的作用 printf("請輸入ch2的字符:>>> "); ch2 = getchar(); printf("\'ch2 = %ctest\'\n",ch2); getchar(); //測試此處getchar()的作用 printf("請輸入ch3的字符:>>> "); scanf("%c",&ch3); //這里第二個參數一定是變量的地址,而不是變量名 printf("ch3 = %c\n",ch3); printf("請輸入a的值:>>> "); scanf("%d",&a); printf("a = %d\n",a); printf("請輸入b的值:>>> "); scanf("%d",&b); printf("b = %d\n",b); return 0; } [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o echo2 echo2.c [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./echo2 請輸入ch1的字符:>>> a ch1 = a 請輸入ch2的字符:>>> b 'ch2 = btest' 請輸入ch3的字符:>>> c ch3 = c 請輸入a的值:>>> 100 a = 100 請輸入b的值:>>> 200 b = 200 [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# [root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]#