C程式設計 | 資料的表現形式及其運算
·在計算機高階語言中,資料的兩種表現形式:
-
常量
-
變數
·常量
1.整型常量:整數常量即1個整數值,有3種數制形式
- 十進位制數:以非0開始的數,如:220、-560、+369
- 八進位制數:以0開始的數,如:06、0106、0677
- 十六進位制數:以0X或0x開始的數,如:0X0D、0XFF、0x4e、0x123等。
2.實型常量:實數常量即1個實數值,有2種表示形式
- 一般形式 由數字、小數點以及必要時的正負號組成,如:29.56、-56.33、0.056、.056、0.0等。
- 指數形式 相當於科學計數法,將a×10^b的數表示如下,aEb 或 aeb(其中:a、E(或e)、b任何一部分都不允許省略,如:2.956E3、-0.789e8、.792e-6等。) 【錯誤表示:e-6、2.365E。】
3.字元常量:字元常量為一個有效字元
- 在程式中須用單引號限定。 如:‘a’ 、‘9’ 、 ‘Z’ 、‘%’。
- 通過鍵盤輸入時,直接輸入字元本身,不加單引號。(eg:轉義字元’\n’,’\012’,’\h1B’)
4.字串常量:字串常量為若干有效字元的一個序列
- 在程式中須用雙引號限定。 如: “Hello world” 、"0.912e8"
- 字串中字元個數稱為字串的長度,允許為0。如: "Hello world"——長度為11、"0.912e8"——長度為7
5.符號常量:可以用一個識別符號來表示一個常量,這個識別符號稱之為符號常量。
- 編譯後寫在程式碼區,不可定址,不可更改,屬於指令的一部分。
- eg:#define PI 3.1416 //注意行末沒有分號
轉義字元及其作用
·變數
變數代表一個有名字的、具有特定屬性的一個儲存單元。 變數用來存放資料,也就是存放變數的值。 在程式執行期間,變數的值是可以改變的。 變數必須先定義,後使用。
·常變數
Const int a=3 //定義a為一個整型變數,指定其值為3,而且在變數存在期間其值不能改變
常變數與常量的異同是: 常變數具有變數的基本屬性: 有型別,佔儲存單元,只是不允許改變其值。可以說,常變數是有名字的不變數,而常量是沒有名字的不變數。有名字就便於在程式中被引用。
#define Pi 3.1415926 //定義符號常量 const float pi=3.1415926; //定義常變數
如上,符號常量Pi和常變數pi都代表3.1415926,在程式中都能使用。但二者性質不同: 定義符號常量用#define指令,它是預編譯指令,它只是用符號常量代表一個字串,在預編譯時僅進行字元替換,在預編譯後,符號常量就不存在了(全置換成3.1415926了),對符號常量的名字是不分配儲存單元的。而常變數要佔用儲存單元,有變數值,只是該值不改變而已。從使用的角度看,常變數具有符號常量的優點,而且使用更方便。有了常變數以後,可以不必多用符號常量。
·識別符號
識別符號就是一個物件的名字。用於標識變數、符號常量、函式、陣列、型別等,識別符號只能由字母、數字和下劃線3種字元組成,且第1個字元必須為字母或下劃線
注意:變數名中區分大小寫字母 、不能使用關鍵字作為變數名、 變數的名字應該儘量反映變數在程式中的作用與含義
C語言中的關鍵字:
·資料型別
所謂型別,就是對資料分配儲存單元的安排,包括儲存單元的長度(佔多少位元組)以及資料的儲存形式。不同的型別分配不同的長度和儲存形式。
資料是計算機程式處理的所有資訊的總稱,C語言共有9種資料型別 。
①整型資料
整型資料型別 |
預設形式的整型資料型別 |
位元組數 |
取值範圍 |
[signed ]int |
int |
4 |
-2147483648~2147483647(-231~231-1) |
unsigned [int] |
Unsigned |
4 |
0~4294967295(0~232-1) |
[signed] short [int] |
short |
2 |
-32768~32767(-215~215-1) |
unsigned short [int] |
unsigned short |
2 |
0~65535(0~216-1) |
[signed ]long [int] |
long |
4 |
-2147483648~2147483647(-231~231-1) |
unsigned long [int] |
unsigned long |
4 |
0~4294967295(0~232-1) |
[signed ]long long [int] |
long long |
8 |
-9223372036854775808~9223372036854775807(-263~263-1) |
unsigned long long [int] |
unsigned long long |
8 |
0~18446744073709551615(0~264-1) |
(說明: C標準沒有具體規定各種型別資料所佔用儲存單元的長度,只要求sizeof(short)≤sizeof(int)≤sizeof(long)≤sizeof(long long),具體由各編譯系統自行決定的。 sizeof是測量型別或變數長度的運算子)
ASCII字符集包括:
- 字母: 大寫英文字母A~Z,小寫英文字母a~z
- 數字: 0~9
- 專門符號: 29個,包括 ! " # & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ _ ` { | } ~
- 空格符: 空格、水平製表符(tab)、垂直製表符、換行、換頁(form feed)
- 不能顯示的字元: 空(null)字元(以'\0'表示)、警告(以'\a'表示)、退格(以'\b'表示)、回車(以'\r'表示)等
ASCII碼錶:
【注意:字元′1′和整數1是不同的概念。 字元′1′只是代表一個形狀為′1′的符號,在需要時按原樣輸出,在記憶體中以ASCII碼形式儲存,佔1個位元組。 而整數1是以整數儲存方式(二進位制補碼方式)儲存的,佔2個或4個位元組。 整數運算1+1等於整數2,而字元′1′+′1′並不等於整數2或字元′2′。】
②字元變數
字元變數是用型別符char定義字元變數。
char c='?'; //定義c為字元型變數並使初值為字元′?′。′?′的ASCII程式碼是63,系統把整數63賦給變數c。
printf("%d %c\n",c,c); //用“%d”格式輸出十進位制整數63,用“%c”格式輸出字元′?′
③浮點型資料
3.14159=3.14159*10^0=0.314159*10^1=314.159*10^-2
由於小數點位置可以浮動,所以實數的指數形式稱為浮點數。 浮點數型別包括float(單精度浮點型)、double(雙精度浮點型)、long double(長雙精度浮點型)。
由於用二進位制形式表示一個實數以及儲存單元的長度是有限的,因此不可能得到完全精確的值,只能儲存成有限的精確度。小數部分佔的位(bit)數愈多,數的有效數字愈多,精度也就愈高。指數部分佔的位數愈多,則能表示的數值範圍愈大。
④實型資料
型別 |
位元組數 |
有效數字 |
數值範圍(絕對值) |
float |
4 |
6 |
0以及1.2*10-38~3.4*1038 |
double |
8 |
15 |
0以及2.3*10-308~1.7*10308 |
long double |
8 |
15 |
0以及2.3*10-308~1.7*10308 |
16 |
19 |
0以及3.4*10-4932~1.1*104932 |
⑤常量的型別
- 從常量的表示形式即可以判定其型別。
- 不帶小數點的數值是整型常量,但應注意其有效範圍。
- 在一個整數的末尾加大寫字母L或小寫字母l,表示它是長整型(long int)。
- 凡以小數形式或指數形式出現的實數均是浮點型常量,在記憶體中都以指數形式儲存。
- C編譯系統把浮點型常量都按雙精度處理,分配8個位元組。
⑥常量、變數與型別
float a=3.14159; //3.14159為雙精度浮點常量,分配8個位元組;a為float變數,分配4個位元組
編譯時系統會發出警告(warning: truncation from ′const double′ to′float′),提醒使用者注意這種轉換可能損失精度,一般不影響結果的正確性,但會影響結果的精度。
可以在常量的末尾加專用字元,強制指定常量的型別:
float a=3.14159f; //把此3.14159按單精度浮點常量處理,編譯時不出現“警告”
long double a = 1.23L; //把此1.23作為long double型處理
型別是變數的一個重要的屬性。變數是具體存在的實體,佔用儲存單元,可以存放資料。
而型別是變數的共性,是抽象的,不佔用儲存單元,不能用來存放資料。
int a; a=3; //正確。對整型變數a賦值
int=3; //錯誤。不能對型別賦值
運算子與表示式
-
運算子
①常用的算數運算子
運算子 |
含義 |
舉例 |
結果 |
+ |
正號運算子(單目運算子) |
+a |
a的值 |
- |
負號運算子(單目運算子) |
-a |
a的算術負值 |
* |
乘法運算子 |
a*b |
a和b的乘積 |
/ |
除法運算子 |
a/b |
a除以b的商 |
% |
求餘運算子 |
a%b |
a除以b的餘數 |
+ |
加法運算子 |
a+b |
a和b的和 |
- |
減法運算子 |
a-b |
a和b的差 |
②自增(++)自減(--)運算子
++i,--i 在使用i之前,先使i的值加/減1
i++,i-- 在使用i之後,使i的值加/減1
++i是先執行i=i+1,再使用i的值;而i++是先使用i的值,再執行i=i+1。【只能用於變數,而不能用於常量或表示式】
建議謹慎使用++和--運算子,只用最簡單的形式,即i++,i--,且把它們作為單獨的表示式。
-
表示式
表示式是一個可以計算的算式,其計算過程按照運算子的優先順序高低和結合性的方向順序進行,同時還要考慮運算物件是否具有相同的資料型別以及是否需要型別轉換。 每個表示式代表著一個確定的值和確定的資料型別。
·算術表示式和運算子的優先順序與結合性
用算術運算子和括號將運算物件(也稱運算元)連線起來的、符合C語法規則的式子稱為C算術表示式。 運算物件包括常量、變數、函式等。 C語言規定了運算子的優先順序(例如先乘除後加減),還規定了運算子的結合性。 在表示式求值時,先按運算子的優先級別順序執行,當在一個運算物件兩側的運算子的優先級別相同時,則按規定的“結合方向”處理。C語言規定了各種運算子的結合方向(結合性), “自左至右的結合方向”又稱“左結合性”,即運算物件先與左面的運算子結合。相反“自右至左的結合方向”稱為“右結合性”。
·不同型別資料間的混合運算
如果一個運算子兩側的資料型別不同,則先自動進行型別轉換,使二者成為同一種類型,然後進行運算。整型、實型、字元型資料間可以進行混合運算。規律為:
- +、-、*、/運算的兩個數中有一個數為float或double型,結果是double型,因為系統將所有float型資料都先轉換為double型,然後進行運算。
- 如果int型與float或double型資料進行運算,先把int型和float型資料轉換為double型,然後進行運算,結果是double型。
- 字元(char)型資料與整型資料進行運算,就是把字元的ASCII程式碼與整型資料進行運算。如果字元型資料與實型資料進行運算,則將字元的ASCII程式碼轉換為double型資料,然後進行運算。
int i=3,j;
float f=2.5;
double d=7.5;
printf("%lf",10+'a'+i*f-d/3);
程式分析:10+'a'+i*f-d/3
- 進行10+′a′的運算,′a′的值是整數97,運算結果為107。
- 由於“*”比“+”優先順序高,先進行i*f的運算。先將i與f都轉成double型,運算結果為7.5,double型。
- 整數107與i*f的積相加。先將整數107轉換成雙精度數,相加結果為114.5,double型。
- 進行d/3的運算,先將3轉換成double型,d/3結果為2.5,double型。
- 將10+′a′+i*f的結果114.5與d/3的商2.5相減,結果為112.0,double型。
例:給定一個大寫字母,要求用小寫字母輸出。
解題思路: 字元資料以ASCII碼儲存在記憶體中,形式與整數的儲存形式相同。 所以字元型資料和其他算術型資料之間可以互相賦值和運算。 大小寫字母之間的關係是:同一個字母,用小寫表示的字元的ASCII程式碼比用大寫表示的字元的ASCII程式碼大32。
#include <stdio.h>
int main()
{
char c1,c2;
c1='A'; //將字元′A′的ASCII程式碼放到c1變數中
c2=c1+32; //得到字元′a′的ASCII程式碼,放在c2變數中
printf("%c\n",c2); //輸出c2的值,是一個字元
printf("%d\n",c2); //輸出c2的值,是字元′a′的ASCII程式碼
return 0;
}
執行結果:
·型別轉換
- 自動型別轉換:在運算時不必使用者干預,系統自動進行的型別轉換。
- 強制型別轉換:當自動型別轉換不能實現目的時,可以用強制型別轉換。
·強制型別轉換運算子
(型別名)(表示式)
- (double)a 將a轉換成double型
- (int)(x+y) 將x+y的值轉換成int型
- (float)(5%3) 將5%3的值轉換成float型
- (int)x+y 只將x轉換成整型,然後與y相加
- int a; float x,y;double b; a=(int)x 進行強制型別運算(int)x後得到一個int型別的臨時值,它的值等於x的整數部分,把它賦給a,注意x的值和型別都未變化,仍為float型。該臨時值在賦值後就不再存在了。