工欲善其事必先利其器,上一章我們講解了VC++6.0的安裝,這一把C語言編程的利器,那麼現在是不是有種把持不住要寫C語言的衝動呢?哈哈,好期待喲!想着要學習C語言,變成編程高手,最後成爲隱藏在複雜網絡背後的一個充滿神祕感的黑客。咳咳,想想都開心!不過學習任何編程語言都需要基礎理論知識的鋪墊,就像我們日常生活中的常識一樣必須去了解它。這樣我們就可以萬丈高樓平地起了。廢話不多說,走起!
2.1 數據類型分類
在現實生活中家庭人口多的買大房子,家庭人口一般的買中等房子,而家庭人口少的適當的就買小房子,這些不同的家庭都是按照自己的實際需求和經濟條件,來選擇適合自己的房子。C語言也是類似。在C語言中就像家庭人口多少一樣。劃分不同的類型。比如:字符型,整型以及浮點型。字符型佔1個字節,家裏人少嘛。整型佔4個字節,屬於人口中等。浮點型和整型一樣,也是佔4個字節。但是如果是雙精度的浮點型這一家人口就比較多了,佔8個字節。
那麼C語言有多少種數據類型呢?請看圖2.1。而各個變量對應的存儲空間大小也會在後續的部分中給出。
2.1.1 常量與變量
常量,顧名思義就是恆定不變的量。在C語言中常量分爲:整型常量、實型常量、字符型常量、字符串常量、符號常量。
整型常量如下:
a = a * 2;
其中的2就是整型數。
實型常量如下:
a = a * 3.1415;
其中的3.1415就是實型常量。
字符型常量如下:
a = 32 + 'A';
其中的'A'就是字符型常量。字符串型常量是多個字符型常量的一個集合。字符型常量是單引號引起來一個字符,而字符串常量則是雙引號引起的多個字符,比如:"ABCD","China","1a2b3c"等。
符號常量如下:
#define N 1024
這就是把N定義爲1024,這個值在程序運行中是不會改變的。預處理命令一般都是以“#”開頭的。
那變量呢?變量,顧名思義就是可以改變的量。整型變量、實型變量、字符型變量、字符串變量。當然後續還會有指針變量、結構體變量、枚舉類型變量等,各種類型的變量。
那麼變量那麼多我們怎麼去定義呢?這就涉及到C語言中的一些關鍵字,我們通過這個關鍵字來定我們所需大小的變量。就像家庭人口多的,我們就定義一個較大的變量關鍵字。如果需要所需存儲空間較小,那麼我們就分配空間較小的關鍵字。這就造成了關鍵的不同。C語言中共有32個關鍵字,如表2.1所示,爲C語言所有的關鍵字。以字母在單詞表中出現的順序排列。
auto |
break |
case |
char |
const |
continue |
default |
do |
double |
else |
enum |
extern |
float |
for |
goto |
if |
int |
long |
register |
return |
short |
signed |
sizeof |
static |
struct |
switch |
typedef |
union |
unsigned |
void |
volatile |
while |
當然裏面有很多我們暫時用不到的關鍵字,那些用不到的關鍵字不用管它。我們只關注暫時用到的關鍵字,這些關鍵字主要有八個:char、short、int、long、float、double、signed、unsigned。
這些關鍵字怎麼使用呢?哈哈,此處賣個關子,在下幾節我們將會對這個八個關鍵字進行詳細的說明。
在絕大多數程序的開頭我們都會見如下定義:
#include <stdio.h>
int main()
{
int a,b;
...
}
在這個程序中,我們發現第4行定義:
int a,b;
其中int爲關鍵字,就是要買的房子的大小。由於我們使用的是VC++6.0的編譯器,所以開闢了4個字節的存儲空間。“a”“b”就是對應的變量名。C語言遵循先定義後使用的原則。現在問題來了,我們爲什麼要定義成a,b呢?爲什麼不定義成其他的名字?如c,bb,ab等。所以這就引出來了變量名的命名規則。也就是比較文藝範說法的“標識符”。
什麼是標識符?標識符是用來表示不同變量相互區分的一種符號。標識符不僅僅是可以表示變量名,還可以表示函數名、文件名,數組名等,這也就解釋爲什麼有時候我們用一些不常見的字符命名文件夾的時候,會命名失敗,並提示出現非法字符。
如何定義標識符?不僅在C語言中,在很多其他的編程語言中,比如C++、java、C#、PHP等編程語言中都遵循標識符規則。
C語言合法命名規則:
- 標識符只能由字母、數字和下劃線構成。
- 第一個字符必須是字母或下劃線。
- 區分字母大小寫。
- 標識符最少是1個字符,最多是32個字符。
常用的有四種命名法則:駝峯命名法、匈牙利命名法、帕斯卡命名法、下劃線命名法。好的命名不僅可以增加程序的可讀性,而且還便於對程序的理解和後期維護。各個命名方法我們就不詳細講解了,我們會在程序中做簡要的講解,這樣比現在枯燥的說明更能加深大家的理解。如果大家想要了解更多詳細的信息,可以尋求百度大神的幫忙。只需要輸入相應的命名方法,就可以百度出巨多的有用信息。
再回到之前的問題,是否可以命名爲c,bb,ab等?回答是肯定的,只要我們滿足上述命名規則即可作爲變量名。但變量名不能相同。
下面幾節該回到我們關鍵字的說明了,在講解關鍵字的同時,我們就可以開啓我們的編程腳步了。一步兩步,一步兩步,似魔鬼的步伐...。咳咳,有點小激動腳步停不下來。
2.1.2 整型數據
整型數據分爲好幾種:基本整型(int型)、短整型(short int型)、長整型(long int型)、雙長整型(long long int型)、無符號整型(unsigned int型)、無符號短整型(unsigned short)、無符號長整型(unsigned long)。無符號類型的整數就是不包括符號位,就是隻能表示正數。而普通的整型既可以表示正數也可以表示負數。廢話不多說直接看錶2.2,這樣比較直觀。
類型 |
取值範圍 |
字節數 |
int(基本整型) |
|
4 |
unsigned int(無符號基本整型) |
|
4 |
short(短整型) |
|
2 |
unsigned short(無符號短整型) |
|
2 |
long(長整型) |
|
4 |
unsigned long(無符號長整型) |
|
4 |
long long(雙長型) |
|
8 |
unsigned long long(無符號雙長型) |
|
8 |
上表2.2中詳細列舉了VC++6.0下各種整型數據取值範圍和所佔字節數。在表內容的第三行我們發現它寫成了:short,沒有int。事實上完整的寫法就是:short int,但實際編程中int可以省略,所以就寫成了表中的形式。其實這也是程序員的習慣寫法。
比如:
short int a = 5;
就可以寫成:
short a=5;
其中long、unsigned long、long long、unsigned long long都是可以省略int的。
下面就讓我們看看如何定義這些變量吧?
- long c = 3;
- unsigned long d = 4;
- long long e = 5;
- unsigned long long f = 6;
在本書中和對於初學者來說,暫時不會把所有的數據類型使用一遍,等我們功力深厚了,自然就會接觸這些知識,相應的就會使用的,在上表所有的類型中我們使用的int基本整型比較多,其他的希望大家後續學習。
當你學完本書之後,估計其他類型你已經開始使用了。所以我們暫時只記住表內容中的第一行就行了。記住喲,是int型,是int型,是int型。重要的事情說三遍喲。對於int型我們將會用如下實例進行說明。
【例2.1】int型的使用。
編寫程序:
#include <stdio.h>
int main()
{
int a;//定義整型變量a
a = 2;//把2賦值給變量a
printf("%d\n", a);//輸出賦值後的變量a
return 0;//正常返回,返回值爲0
}
運行結果:
2
Press any key to continue
程序分析:我們第四行定義一個int型變量a,然後用“=”號的形式,把2賦值給變量a。最後用printf函數輸出int型變量a的值2。printf函數中的“%d”表示以十進制形式輸出。printf函數我們將會在下一章進行講解。大家暫時就按照我所寫的格式寫即可。
終於開始了我們的程序路。
2.1.3 實型數據
如果說上節的整型沒有小數位,那麼現在要隆重登場的“實型數據”就具有小數位了。
實型數據有時候我們又稱浮點型數據。用來表示具有小數點的實數。在C語言中,浮點型數據是以指數形式存儲在內存單元中的。比如地球的重量是,它的表示形式就是指數形式。
浮點數類型包括float(單精度浮點型)、double(雙精度浮點型)、long double(長雙精度浮點型)。同樣不廢話,直接上表2.3。
類型 |
取值範圍 |
字節數 |
有效字節 |
float(單精度浮點型) |
4 |
6 |
|
double(雙精度浮點型) |
8 |
15 |
|
long double(長雙精度浮點型) |
8 |
15 |
實際上不同的編譯器對long double型分配不同的存儲空間,大家在使用不同的編輯器時需要注意此點。由於我們使用的是VC++6.0,所以分配了8個字節。如果使用Turbo C編譯器,會分配16個字節。所以不同的編輯器對於同一類型可能分配不同的存儲空間。上一節的整型也是如此。因爲對於現階段編寫的程序來說,不會劍走偏鋒搞細節。這也是爲什麼上節並無詳解相關信息。等大家有了基礎就會究其細節,再做研究了。定能全面掌握。
在表的最後一列,出現了有效字節。那麼我們就需要了解一些二進制了。實際上計算機中是用二進制來表示小數部分以及用2的冪次來表示指數部分。在32位系統中,多少位表示小數部分,多少位表示指數部分,是由具體的編譯器決定的。有的編譯系統以24位表示小數部分和符號,用8位表示指數部分。由於存儲單元的長度有限,用二進制表示一個實數是不可能得到完全精確的值的,只能儘可能的接近我們所需的值。小數部分佔的位數越多,有效數字就越多,精度也就越高。指數部分佔的位數越多,能表示的數值範圍越大。
比如:
float f = 314.159;
又可表示爲:
float f = 3.14159*e100;
雙精度的表示:
double d = 3.1415926;
那麼我們具體會用到浮點數類型的那些關鍵字呢?由於我們使用的編譯器VC++6.0,所以double和long double其實是一樣的。我們編程中常用到float和double類型,float和double類型,float和double類型喲!
【例2.2】float和double類型的使用。
編寫程序:
#include <stdio.h>
int main()
{
float f;//定義單精度浮點數f
double d;//定義雙精度浮點數d
f = 2.34;//把2.34賦值給單精度f
//輸出賦值後的結果,%f表示以單精度格式輸出結果,"\n"表示換行
printf("%f\n", f);
d = 3.1415;//把3.1415賦值雙精度d
//輸出賦值後的結果,%lf表示以雙精度格式輸出結果
printf("%lf\n", d);
return 0;
}
運行結果:
2.340000
3.141500
Press any key to continue
程序分析:第4行定義單精度變量f。第5行定義雙精度變量d。第6行把2.34賦值給單精度變量f。第8行輸出單精度f的結果。第9行把3.1415賦值給雙精度變量d。第11行輸出雙精度d的結果。printf函數中的%f和%lf分別表示以單精度格式輸出和以雙精度格式輸出。我們將會在下一章進行講解。
2.1.4 字符型數據
C99中把字符類型看做是整型的一種,因爲字符是按照整數的形式存儲的。大多數系統採用的是ASCII字符集,都包括127個字符。具體請參考附錄CASCII表。在ASCII表中,我們會發現有:字母、數字、專門符號、空格符、還有一些不能顯示的字符。在ASCII表中可以看到有大寫字母和小寫字母,他們對應不同的十進制值。
字符型數據包括兩種。一種是signed char(有符號字符型)。一種是unsigned char(無符號字符型)。詳細信息看錶2.4。
類型 |
取值範圍 |
字節數 |
signed char(無符號字符型) |
1 |
|
unsigned char(無符號字符型) |
1 |
我們之前已經說過,由於字符是按照整型形式在內存中存儲的,所以字符型變量即可以賦值爲整數,又可以賦值爲字符。首先我們看看如何賦值爲整數。
比如:
- signed char a = 65;
- unsigned char b = 66;
如果我們輸出a和b對應的字符,就會發現結果分別爲字符‘A’和字符‘B’。因爲在ASCII表中整數65對應的字符爲‘A’,66爲‘B’。詳情請參考附錄C。
定義變量時如果即不加signed,又不加unsigned時,不同的編輯器會自動添加上signed或者unsigned,視編譯器而定。我們使用的是VC++6.0,所以默認爲signed char。我們可以通過程序2.3進行驗證。
【例2.3】char的默認值。
編寫程序:
#include <stdio.h>
int main()
{
signed char a;//定義有符號變量a
unsigned char b;//定義無符號變量b
char c;//定義默認字符變量c
//把a,b,c的值都初始化爲127
a = 127;
b = 127;
c = 127;
//讓a,b,c的值都自加1
a = a + 1;
b = b + 1;
c = c + 1;
//最後輸出三種定義形式的整數值
printf("a = %d\n", a);
printf("b = %d\n", b);
printf("c = %d\n", c);
return 0;
}
運行結果:
a = -128
b = 128
c = -128
Press any key to continue
程序分析:我們首先在第4~6行定義三個變量,第一個變量是有符號的a,第二個變量是無符號的b,第三個變量是默認形式的c。然後在第8~10行給這個三個變量分別賦值。a賦值爲127,b賦值爲127,c賦值爲127。爲什麼賦值爲127呢?因爲有符號的字符最大值是127,我們只需要查看他們對應變量增加1後,變量c的結果值與哪一個相同,那麼就會默認爲那種類型。所以第12~14行對應變量增加1。第16~18爲要輸出的結果。我們從運行結果中發現變量c的值和變量a的值相同,這就說明如果char之前不加關鍵字signed或unsigned,則默認爲signed。注意printf函數中的%d表示以整數形式輸出,詳細信息我們將會在下一章介紹。
上面是以整數形式來說明字符變量的,因爲字符是按照整數形式存儲的。下面我們看一看字符的表示形式。
比如signed char和unsigned char的定義:
- signed char a = 'A';
- unsigned char b = 'B';
在賦值方式上,兩者不沒有區別,只是在取值範圍上有區別。我們將會在下一個例題中介紹。
【例2.4】char基本操作。
編寫程序:
#include <stdio.h>
int main()
{
signed char a = 'A';//定義並初始化有符號變量a
unsigned char b = 'B';//定義並初始化無符號變量b
//輸出變量a和變量b的值
printf("%c\n", a);
printf("%c\n", b);
//變量a和變量b分別32後,再賦值給自己
a = a + 32;
b = b + 32;
//輸出變量a和變量b改變後的值
printf("%c\n", a);
printf("%c\n", b);
return 0;
}
運行結果:
A
B
a
b
Press any key to continue
程序分析:第4行定義了一個有符號的變量a,第5行定義了無符號的變量b。第7~8行輸出對應變量初始化的值。第10~11行讓有符號的變量和無符號的分別加32,然後再賦值給自己。我們之前已經說過字符可以賦值給整數,由於‘A’和‘B’分別對應的ASCII值爲65和66。它們加32再賦值給自己後‘A’、‘B’對應的值分別是97和98。所以我們在第13~14行以字符形式輸出的結果爲‘a’、‘b’。‘a’對應的ASCII值爲97,‘b’對應的ASCII值爲98。記得參考附錄C喲。注意%c表示以字符形式輸出結果,我們仍會在下一章進行講解。
2.2 N-S與流程圖簡介
略