一、數據類型
1、概念
(1)標識符
1.定義:用來標記常量、變量、函數及文件名字的字符序列。
2.構成規則:只能由數字、字母、下划線三部分組成,且不能以數字開頭,並且嚴格區別大小寫,不能定義為系統中存在的關鍵字。
(2)關鍵字
c語言中具有特定含義、專門用作語言特定成分的一類標識符
注:在C語言中,所有的關鍵字都有固定的意義,不能用作其它,且所有的關鍵字都必須小寫
(3)c的數據類型
數據是操作的對象,數據類型是指數據的內在表現形式(代碼、存儲、運算)
(4)常量和變量
1. 常量
【1】常量:在程序運行過程中,其值不能被改變的量
常量區分為不同類型(表示形式),如:12、1.0、‘a’
【2】符號常量:用一個標識符代表的一個常量
定義方法:#define 標識符 常量
#define PRICE 30
#include <stdio.h> void main() { int num,total; num = 10; total = num * PRICE; printf("total = %d",total); }
2. 變量
【1】變量:其值是可以改變的量,它用標識符(變量名)來表示,在內存中占據一定的存儲單元
變量的定義方法: 類型符 標識符
注意事項:<1>見名知意 <2>先定義后使用 <3>習慣上,符號常量名用大寫,變量名用小寫,以示區別
【2】變量賦初值
變量先定義,后使用,一般放在函數開頭
變量初始化:可以在定義時賦初值
2、整型數據
(1)整型常量
1. 各種進制的整數表示方法
十進制整數:由數字0~9和正負號表示. 如 123,-456,0
八進制整數:由數字0開頭,后跟數字0~7表示. 如 0123,011
十六進制整數:由0x開頭,后跟0~9,a~f,A~F表示. 如 0x123,0xff
2. 整型常量的類型
【1】整型常量的值在-32768~+32767范圍內,編譯器認為是int類型
【2】整型常量的值超過上述范圍,而在-2147483648 ~ +2147483647范圍內,編譯器認為是long類型
【3】當系統定義short int與int占內存長度相同,則兩種類型常量均可以賦給 int和short int型變量
【4】在整型常量后面加大寫L或小寫l,則告訴編譯器,把該整型常量作為long類型處理。例:123L、0L
【5】在整型常量后面加u,則按無符號整型方式存放,負數轉換成補碼再按無符號整型方式存放。
(2)整型變量
1. 整型數據在內存中的存放形式以二進制的補碼表示,每一個整型變量在內存中占2個字節
【1】內存以字節為單元組成,每個字節有一個地址,一個字節一般由8個二進制位組成,每個二進位的值是0或1。
【2】數值的表示方法——原碼、反碼和補碼
原碼:最高位為符號位,其余各位為數值本身的絕對值
反碼: 正數:反碼與原碼相同
負數:符號位為1,其余位對原碼取反
補碼: 正數:原碼、反碼、補碼相同
負數:最高位為1,其余位為原碼取反,再對整個數加1
負數補碼轉換成十進制數:最高位不動,其余位取反加1
補碼:11111001 取反:10000110 加1: 10000111=-7
補:整型數據的溢出
此情況稱為“溢出”,運行時不報錯,編程時要注意
2. 整型變量的分類
補:整數類型和取值范圍
int 16位 -32768~32767
short int 16位 -32768~32767
long int 32位 -2147483648~2147483647
unsigned int 16位 0~65535
unsigned short int 16位 0~65535
unsigned long int 32位 0~4294967295
3. 整型變量的定義
int a,b; long num,i,j; unsigned short c,d;

#include <stdio.h> void main() { int a,b,c,d; unsigned u; a = 12; b = -24; u = 10; c = a + u; d = b + u; printf("a+u=%d , b+u=%d\n",c,d); }
3、實型(浮點型)數據
(1)實型常量
1. 浮點數(float)又稱為實數(real),有兩種表示形式:
【1】十進制小數形式:必須有小數點 如 0.123 、.123 、123.0 、0.0 、123.
【2】指數形式:必須有e或E,e前e后必須有數字,且e后必須是整數 如 123.456e0、12.3456e1 、1.23456e2 、 0.123456e3 、0.0123456e4 等
【3】類型:缺省 double
后綴 f 或 F --> 為 float 型 ; 后綴 l 或 L --> 為 long double 型
2. 浮點型常量的類型
浮點型常量一般按雙精度64位處理,數后加 F 或 f 按單精度 ,浮點型常量不分 float 和 double。
(2)實型變量(取值范圍與值的精度與機器有關)
單精度(float型):占4個字節,7位有效數字 (3.4e-38~3.4e+38)
雙精度(double型):占8個字節,15~16位有效數字 (1.7e-308~1.7e+308)
long double型:占10個字節,15~16位有效數字 (3.4e-4932~1.1e+4932)
float x,y; (指定x、y為單精度浮點型變量) double z; (指定z為雙精度浮點型變量) long double t; (指定t為長雙精度浮點型變量)
(3)實型數據的舍入誤差
1. 浮點型數據在內存中的存放形式
浮點型數據在內存中占4個字節(32位),在內存中分成3部分,指數為2的冪次
2. 數據超過有效位數,則被舍去,故可能產生誤差。要避免一個很大的數與一個很小的數加減

#include <stdio.h> void main( ) { float a , b; a= 123456.789e5; b= a+20; printf("%f \n",b); //12345678848.000000 }
注:舍入誤差使1.0/3*3 的結果並不等於1 !
4、字符型數據
(1)字符常量
1. 概念
【1】定義:用單引號括起來的單個字符或轉義字符(如 ‘a’ ‘A’ ‘\n’ ‘\t ’ )
【2】字符常量的值:該字符的ASCII碼值(如 ‘a’——97 ,‘A’——65 ‘\n’——10, ‘\t’——9)
【3】定義格式:char 變量名 = 值
char ch=65 與 char ch=‘A’ 與char=‘\101’是等效的
2. 轉義字符:反斜線后面跟一個字符或一個代碼值表示,特殊的字符常量,它們都以 ‘\’開頭(代表一個字符)

#include <stdio.h> void main( ) { printf(“ ab c\t de\rf\tg\n”); printf(“h\ti\b\bj k”); } /* 顯示結果: f gde h j k */
(2)字符變量
1. 字符變量用來存放字符,且只能存放一個字符,占用一個字節。
2. 定義方法: char c1,c2; 賦值方法:c1=‘a’ ; c2=‘\101’ (A); c3 = 0xff (255); c4='\377'(255);
(3)字符數據存儲
1. 以二進制存放字符的ASCII碼值(0~255整數),與整數的存儲形式類似
#include <stdio.h> void main( ) { char c1,c2 ; c1=97 ;c2=98 ; printf(“%c %c \n",c1,c2); //a b c1='a' ;c2='b' ; printf(“%c %c \n",c1,c2); //a b }
2. 字符數據與整型數據可以相互賦值
3. 字符數據可以以字符或整數形式輸出
#include <stdio.h> void main( ) { int i; char c; i = 'a'; c = 97; printf(“%c %d \n",i,i); // a 97 printf(“%c %d \n",c,c); // a 97 }
補:
#include <stdio.h> void main( ) { char c; c = '\376'; printf(“%c ,%d \n",c,c); // () 254 } #include <stdio.h> void main( ) { unsigned char c; c = '\376'; printf(“%c ,%d \n",c,c); // () -2 }
(3)字符串常量
1. 定義:用一對雙引號(“ ”)括起來的字符序列。如:“How do you do” , “CHINA” , “a” , “$123.45”
2. 存儲:每個字符串尾自動加一個 ‘\0’ 作為字符串結束標志
字符串“hello”在內存中
空串 “”
沒有字符串變量, 只能用字符數組存放
5、各類數值型數據間的混合運算
整型、實型、字符型數據間可以混合運算
(1)什么情況下發生自動轉換
1. 運算轉換------不同類型數據混合運算時
2. 賦值轉換------把一個值賦給與其類型不同的變量時
3. 輸出轉換------輸出時轉換成指定的輸出格式
4.函數調用轉換------實參與形參類型不一致時轉換
(2)運算轉換規則:不同類型數據運算時先自動轉換成同一類型
(3)強制轉換
一般形式:(類型名)(表達式)
例:(int)(x+y), (int)x+y, (double)(3/2) ,(int)3.6
說明:強制轉換得到所需類型的中間變量, 原變量類型不變
#include <stdio> main() { float x; int i; x=3.6; i=(int)x; //表達式僅一個變量時,括號可以省略 printf(“x=%f,i=%d”,x,i); } //結果:x=3.600000,i=3
注:較高類型向較低類型轉換時可能發生精度損失問題
二、運算符和表達式
1、c運算符(34種)
2、算術運算符和算術表達式
(1)基本算術運算符: + - * / %
說明:【1】 “-”可為單目運算符時,右結合性
【2】兩整數相除,結果為整數
【3】%要求兩側均為整型數據
【4】+ - * / 運算的兩個數中有一個數為實數,結果是double型
(2)自增、自減運算符++ --
前置 ++i, - -i (先執行i+1或i-1,再使用i值)
后置 i++,i- - (先使用i值,再執行i+1或i-1)
注意:【1】自增、自減運算符只能用於變量,而不能用於常量或表達式
【2】++ 和 - - 的優先級高於算數運算符,結合方向“自右向左”
如:-i++ 相當於 - (i++)
3、賦值運算符和賦值表達式
(1)簡單賦值運算符" = "
用法: 變量標識符 = 表達式
作用:將一個數據(常量或表達式)賦給一個變量 ,左側必須是變量,不能是常量或表達式
(2)類型轉換
賦值轉換規則:使賦值號右邊表達式值自動轉換成其左邊變量的類型
【1】實型數據(包括單、雙精度)賦給整型變量時,舍棄實數的小數部分
【2】整型數據賦給單、雙精度變量時,數值不變,但以浮點數形式存儲到變量中
【3】長度相同的有符號與無符號整型數間,原樣賦值,但數值有時會有變化
#include <stdio> void main() { unsigned a; int b = -1; a = b; printf(“%d , %u \n”,b,a); //b=-1 a=65535 a = 65534u; b = a; printf(“%d , %u \n”,b,a); //b=-2 a=65534 }
【4】char、int、long 等類型的轉換
1)“短”數據賦給“長”變量
符號擴展:若最高位位1(負數),則變量高字節位補1;反之,補0。
2)“長”數據賦給“短”變量
只將數據的低字節位原封不動送到變量中(數據有可能有差錯)
(3)復合賦值運算符
在賦值符“ = ”之前加上其它運算符,構成復合賦值運算符
種類:+= -= *= /= %= 《= 》= &= ^= |=
(4)賦值表達式
形式:<變量> <賦值運算符> <表達式>
賦值表達式的值與變量值相等,且可嵌套
表達式中允許出現運算符號、變量、數值、函數
4、逗號運算符和逗號表達式
形式:表達式1,表達式2,……表達式i
作用:用於連接表達式,如:3+5,3+6
一個逗號表達式又可以與另一個表達式組成一個新的逗號表達式
逗號運算符是所有運算符中級別最低的
注意:並不是任何地方出現的逗號都是逗號運算符,如:printf(" %d , %d ,%d " ,a,b,c)
a=3*5,a*4 //a=15,表達式值60 a=3*5,a*4,a+5 //a=15,表達式值20 x=(a=3,6*3) //賦值表達式,表達式值18,x=18 x=a=3,6*a //逗號表達式,表達式值18,x=3 a=1;b=2;c=3; printf(“%d,%d,%d”,a,b,c); //1,2,3 printf(“%d,%d,%d”,(a,b,c),b,c); //3,2,3
5、關系運算符和關系表達式
“關系運算”即“比較運算,是對兩個值進行比較,比較的結果是得到真假兩種值。
(1)關系運算符
【1】關系運算符及其優先次序
1—>種類(6種關系運算符): <= == >= > !=
2—>結合方向:自左向右
3—>優先級別:算術運算符 > 關系運算符 > 賦值運算符
< (小於) 、<= (小於等於) 、 > (大於) 、 > = (大於等於) ——> 優先級6(高)
= = (等於) 、 ! = (不等於) ——> 優先級7(低)
(2)關系表達式:用關系運算符將兩個表達式連接起來的式子
a>b , (a+b)>(b+c) , 5==3
【1】關系表達式的值:是邏輯值“真”或“假”,用1和0表示
int a=3,b=2,c=1,d,f; a>b //表達式值1 (a>b)==c //表達式值1 b+c<a //表達式值0 d=a>b // d = 1 f=a>b>c // f = 1
【2】關系運算注意事項

//>結合方向自左至右 5>2>7>8 // 0 int i=1, j=7,a; a=i+(j%4!=0); // a=2 // 用ASCII值比較 ‘a’>0 // 結果為1 ‘A’>100 // 結果為0
應避免對實數作相等或不等於0的判斷,如 1.0/3.0*3.0==1.0 可改寫為:fabs(1.0/3.0*3.0-1.0)<1e-6
注意區分“ = ”與“ = = ”
int a = 0,b = 1; if(a = b) printf(“a equal to b”); else printf(“a not equal to b”);
6、邏輯運算符和邏輯表達式
(1)邏輯運算符: C語言提供3種邏輯運算符
“!”是單目運算符 、 “&&”和“ ||”是雙目運算符
【1】邏輯運算真值表
【2】邏輯運算符的優先次序
1—>優先次序:!(非) > &&(與) > ||(或)
2—>結合方向:從右向左 從左向右 從左向右
(2)邏輯表達式: 用邏輯運算符將關系表達式或邏輯量連接起來的式子就是邏輯表達式。
【1】C語言中, 運算量 0表示“假”,運算結果 0表示“假”, 非0表示“真”, 1表示“真”。
a=4;b=5; !a //0 a&&b //1 a||b //1 5>3&&2||8<4-!0 //1 ‘c’&&‘d’ //1 !a||b //1 4&&0||2 //1
【2】邏輯運算中的注意點:
短路特性:邏輯表達式求解時,並非所有的邏輯運算符都被執行,只是在必須執行下一個邏輯運算符才能求出表達式的解時,才執行該運算符。
a&&b&&c //只在a為真時,才判別b的值;只在a、b都為真時,才判別 c的值 a||b||c //只在a為假時,才判別b的值;只在a、b都為假時,才判別 c的值
a=1;b=2;c=3;d=4;m=1;n=1; (m=a>b)&&(n=c>d) //結果 m=0,n=1
【3】復雜邏輯條件的表述

//判別閏年的條件(int year): //能被4整除: year%4==0 //能被4整除但不能被100整除: (year%4==0)&&(year%100!=0) //能被400整除: year%400==0 //綜合起來: ((year%4==0)&&(year%100!=0))||year%400==0 /優化語句: (year%4==0&&year%100!=0)||year%400==0
7、條件運算符(表達式1 ? 表達式2 : 表達式3)
條件運算符是 C 語言中唯一的三目運算符
if (a>b) max=a; else max=b; //等價於 max=(a>b)? a:b;
條件運算符說明:條件運算符可嵌套,優先級: 13,結合方向自右向左
表達式1?表達式2:表達式3 類型可以不同,表達式值取表達式2和表達式3中較高的類型

x>0?1:(x<0?-1:0)
x?‘a’:‘b’ //x=0,表達式值為‘b’; x≠0,表達式值為‘a’ x>y?1:1.5 //x>y ,值為1.0; x<y ,值為1.5