二、變量與進(jìn)制
本章專題脈絡(luò)

1、關(guān)鍵字(keyword)
定義:被C語言賦予了特殊含義,用做專門用途的字符串(或單詞)。
特點(diǎn):全部關(guān)鍵字都是小寫字母。
舉例:HelloWorld案例中,出現(xiàn)的關(guān)鍵字有 int、return等,這些單詞已經(jīng)被C語言定義好了。
傳統(tǒng)的C語言(ANSI C)有32個關(guān)鍵字。如下:
| 類型 | 具體關(guān)鍵字 |
|---|---|
| 控制語句關(guān)鍵字(12 個) | break, case, continue, default, do, else, for, goto, if, return, switch, while |
| 數(shù)據(jù)類型關(guān)鍵字(12 個) | char, enum, double, long, float, int, short, signed, struct, unsigned, union, void |
| 存儲類型關(guān)鍵字(4 個) | auto, extern, register, static |
| 其他關(guān)鍵字(4 個) | const, sizeof, typedef, volatile |
后續(xù),1999年,C99標(biāo)準(zhǔn)增加了5個關(guān)鍵字:inline、restrict、_Bool、_Complex和_Imaginary。
2011年,C11標(biāo)準(zhǔn)又增加了7個關(guān)鍵字:_Alignas、_Alignof、_Atomic、_Static_assert、_Noreturn、_Thread_local和_Generic。
說明:
1、ANSI C、C99和C11,它們之間差別并不大,在大多數(shù)情況下,它們都是和諧共處的。
2、不需要死記硬背,學(xué)到哪里記到哪里即可。
2、標(biāo)識符(Identifier)
C語言中變量、函數(shù)、數(shù)組名、結(jié)構(gòu)體等要素命名時使用的字符序列,稱為標(biāo)識符。
技巧:凡是自己可以起名字的地方都叫標(biāo)識符。
標(biāo)識符的命名規(guī)則(必須遵守的硬性規(guī)定)
- 只能由26個英文字母大小寫,0-9 或 _ 組成
- 數(shù)字不可以開頭
- 不可以是關(guān)鍵字,但可以包含關(guān)鍵字
- C99和C11允許使用更長的標(biāo)識符名,但是編譯器只識別前63個字符。(會忽略超出的字符)
- 不允許有空格。
- 嚴(yán)格區(qū)分大小寫字母。比如:Hello、hello是不同的標(biāo)識符。
標(biāo)識符的命名建議(建議遵守的軟性要求)
-
在起名字時,為了提高閱讀性,要盡量有意義,“見名知意”。如:sum,name,max,year,total 等。
-
不要出現(xiàn)僅靠大小寫區(qū)分不同的標(biāo)識符。如:name、Name 容易混淆
-
盡量避免名字中出現(xiàn)數(shù)字編號,如value1、value2等,除非邏輯上需要編號。
-
習(xí)慣上,所有宏定義、枚舉常數(shù)、常量(只讀變量)全用大寫字母命名,用下劃線分隔單詞。
比如: const double TAX_RATE = 0.08; //TAX_RATE 只讀變量
-
系統(tǒng)內(nèi)部使用了一些下劃線開頭的標(biāo)識符(比如兩個下劃線開頭的變量名、一個下劃線 + 大寫英文字母開頭的變量名)。比如,C99 標(biāo)準(zhǔn)添加的類型
_Bool。為防止沖突,建議用戶盡量避免使用下劃線開頭的標(biāo)識符。 -
下劃線通常用于連接一個比較長的變量名。如:max_classes_per_student。
-
變量名、函數(shù)名:多單詞組成時,第一個單詞首字母小寫,第二個單詞開始每個單詞首字母大寫:xxxYyyZzz (駝峰法,小駝峰)。比如:
short stuAge = 20;,tankShotGame。
舉例:合法的標(biāo)識符:
a、BOOK1、_sun、MAX_SIZE、Mouse、student23、Football、FOOTBALL、max、_add、num_1、sum_of_numbers
舉例:非法的標(biāo)識符:
$zj、3sum、ab#cd、23student、Foot-baii、s.com、b&c、j**p、book-1、tax rate、don't
【武漢科技大學(xué)2019研】
以下均是合法變量名的是( )。
A.#name total
B.node value_max
C._var long
D.stu-code a+b【答案】B
【解析】C語言中變量名只能包含數(shù)字,字母和下劃線,且只能以字母和下劃線開始。A項(xiàng)含非法字符#,錯誤;C中l(wèi)ong為關(guān)鍵字,變量不能以關(guān)鍵字命名;D中含非法字符-和+。
【四川大學(xué)2017研】以下不合法的用戶標(biāo)識符是( )。
A.J2_KEY
B.Double
C.4d
D._8_【答案】C
【解析】標(biāo)識符只能包含數(shù)字,字母,下劃線,且不能以數(shù)字開頭,選項(xiàng)C錯誤。
練習(xí)
下列定義變量的語句中錯誤的是( )。
A.double int_;
B.float US$;
C.char For;
D.int _int;【答案】B【解析】標(biāo)識符由字母、數(shù)字、下劃線組成。$是非法字符,不能出現(xiàn)在標(biāo)識符中。答案選擇B選項(xiàng)。
3、變量(variable)
3.1 為什么需要變量

一花一世界,如果把一個程序看做一個世界或一個社會的話,那么變量就是程序世界的花花草草、萬事萬物。即,變量是程序中不可或缺的組成單位,最基本的存儲單元。
3.2 初識變量
-
變量的概念:
-
內(nèi)存中的一個存儲區(qū)域,該區(qū)域的數(shù)據(jù)可以在同一類型范圍內(nèi)不斷變化。
-
通過變量名,可以訪問這塊內(nèi)存區(qū)域,獲取里面存儲的值。
-
變量的構(gòu)成包含三個要素:
數(shù)據(jù)類型、變量名、存儲的值 -
C語言中變量聲明的格式:
數(shù)據(jù)類型 變量名 = 變量值
-

-
變量的作用:用于在內(nèi)存中保存數(shù)據(jù)。
-
使用變量注意:
- C語言中每個變量必須先聲明,后使用。
- 不同的數(shù)據(jù)類型,占用的空間大小不一樣。
- 一旦聲明,變量的類型就不能在運(yùn)行時修改。
3.3 變量的聲明與賦值
步驟1:變量的聲明
格式:
數(shù)據(jù)類型 變量名; //聲明變量的語句必須以分號結(jié)尾
舉例1:
int width;
舉例2:
int width,height;
// 等同于
int width;
int height;
步驟2:變量的賦值
變量聲明時,就為它分配內(nèi)存空間,但是不會清除內(nèi)存里面原來的值。這導(dǎo)致聲明變量以后,變量會是一個隨機(jī)的值。所以,變量一定要賦值以后才能使用。
int age; //變量的聲明
age = 18; //變量的賦值
變量的聲明和賦值,也可以寫在一行。
int age = 18;
多個相同類型變量的賦值,可以寫在同一行。
int a = 1, b = 2;
int a, b;
a = 1;
b = (a = 2 * a);
int a, b, c, x, y;
a = b = c = x = y = 10; //連續(xù)賦值
注意:聲明變量以后,不用忘記初始化賦值!定義變量時編譯器并不一定清空了這塊內(nèi)存,它的值可能是無效的數(shù)據(jù),運(yùn)行程序,會異常退出。
3.4 變量的作用域(scope)
-
變量的作用域:其定義所在的一對{ }內(nèi)。
-
變量只有在其
作用域內(nèi)才有效。出了作用域,變量不可以再被調(diào)用。 -
同一個作用域內(nèi),不能定義重名的變量。
-
C 語言的變量作用域主要有兩種:文件作用域(file scope)和塊作用域(block scope)。
文件作用域(file scope)指的是,在源碼文件頂層聲明的變量,從聲明的位置到文件結(jié)束都有效。
int x = 1;
int main() {
printf("%d\n", x);
return 0;
}
塊作用域(block scope)指的是由大括號( {} )組成的代碼塊,它形成一個單獨(dú)的作用域。凡是在塊作用域里面聲明的變量,只在當(dāng)前代碼塊有效,代碼塊外部不可見。
int main() {
int m = 10;
if (m == 10) {
int n = 20;
printf("%d %d\n", m, n); // 10 20
}
printf("%d\n", m); // 10
printf("%d\n", n); // 超出作用域,報錯
return 0;
}
最常見的塊作用域就是函數(shù),函數(shù)內(nèi)部聲明的變量,對于函數(shù)外部是不可見的。 for 循環(huán)也是一個塊作用域,循環(huán)變量只對循環(huán)體內(nèi)部可見,外部是不可見的。
for (int i = 0; i < 10; i++){
printf("%d\n", i);
}
printf("%d\n", i); // 超出作用域,報錯
3.5 變量按類型的分類
變量可以按數(shù)據(jù)類型來分,也可以按聲明的位置來分(全局變量、局部變量)。本節(jié)主講變量的不同類型。
C 語言中的變量按照數(shù)據(jù)類型分為:

注意1:這里列舉的是C語言的常用類型,后續(xù)C語言版本還有新增的類型。
注意2:空類型:void 表示空類型(無類型)。通常應(yīng)用于函數(shù)的返回值類型、函數(shù)的參數(shù)、指針類型。
注意3:在C語言中,沒有
字符串類型,使用字符數(shù)組表示字符串。
4、基本數(shù)據(jù)類型
4.1 整數(shù)類型
4.1.1 類型說明
-
C語言規(guī)定了如下的幾類整型:短整型(short)、整型(int)、長整型(long)、更長的整型(long long)
-
每種類型都可以被 signed 和unsigned 修飾。其中,
- 使用
signed 修飾,表示該類型的變量是帶符號位的,有正負(fù)號,可以表示負(fù)值。默認(rèn)是signed。 - 使用
unsigned 修飾,表示該類型的變量是不帶符號位的,沒有有正負(fù)號,只能表示零和正整數(shù)。
- 使用
-
bit(位):計算機(jī)中的最小存儲單位。
byte(字節(jié)):計算機(jī)中基本存儲單元。
1byte = 8bit
| 類型 | 修飾符 | 占用空間 | 取值范圍 |
|---|---|---|---|
| short [int] | signed | 2個字節(jié)(=16位) | -32768 ~ 32767 (-$2^{15}$ ~ $2^{15}$-1) |
| short [int] | unsigned | 2個字節(jié)(=16位) | 0 ~ 65535 (0 ~ $2^{16}$-1) |
| int | signed | 通常4個字節(jié) | -2147483648 ~ 2147483647 (-$2^{31}$ ~ $2^{31}$-1) |
| int | unsigned | 通常4個字節(jié) | 0 ~ 4294967295 (0 ~ $2^{32}$-1) |
| long [int] | signed | 4個或8個字節(jié) | 4字節(jié)時:-2147483648 ~ 2147483647 (-$2^{31}$ ~ $2^{31}$-1) |
| long [int] | unsigned | 4個或8個字節(jié) | 4字節(jié)時:-0 ~ 4294967295 (0 ~ $2^{32}$-1) |
long long int是C99新增的:
| 類型 | 修飾符 | 占用空間 | 取值范圍 |
|---|---|---|---|
| long long [int] | signed | 8個字節(jié)(=64位) | -9223372036854775808~ 9223372036854775807(-$2^{63}$ ~ $2^{63}$-1) |
| long long [int] | unsigned | 8個字節(jié)(=64位) | 0 ~ 18446744073709551615(0 ~ $2^{64}$-1) |
說明1:不同計算機(jī)的 int 類型的大小是不一樣的。比較常見的是使用4個字節(jié)(32位)存儲一個 int 類型的值,具體情況如下:
| 類型 | 16位編譯器 | 32位編譯器 | 64位編譯器 |
|---|---|---|---|
| short int | 2字節(jié) | 2字節(jié) | 2字節(jié) |
| int | 2字節(jié) | 4字節(jié) | 4字節(jié) |
| unsigned int | 2字節(jié) | 4字節(jié) | 4字節(jié) |
| long | 4字節(jié) | 4字節(jié) | 8字節(jié) |
| unsigned long | 4字節(jié) | 4字節(jié) | 8字節(jié) |
| long long | 8字節(jié) | 8字節(jié) | 8字節(jié) |
說明2:C標(biāo)準(zhǔn)雖然沒有具體規(guī)定各種類型數(shù)據(jù)所占用存儲單元的長度,但幾條鐵定的原則(ANSI/ISO制訂的):
① sizeof(short int) ≤ sizeof(int) ≤ sizeof(long int) ≤ sizeof(long long),具體由各編譯系統(tǒng)自行決定的。其中,sizeof是測量類型或變量長度的運(yùn)算符。② short int至少應(yīng)為2字節(jié),long int至少應(yīng)為4字節(jié)。
這樣約定的好處就是使得C語言可以長久使用。現(xiàn)在的主流CPU是64位,可以預(yù)測不久的將來會推出128位甚至256位的CPU,但是在C語言剛剛出現(xiàn)的時候,CPU還是以8位和16位為主。如果那時候就將整型定死為8位或16位,那么現(xiàn)在我們肯定不會再學(xué)習(xí)C語言了。
說明3:
最常用的整型類型為:int類型。
整數(shù)型常量,默認(rèn)為int類型。
4.1.2 舉例
舉例1:對于 int 類型,默認(rèn)是帶有正負(fù)號的。即 int 等同于 signed int 。一般情況下,關(guān)鍵字signed省略不寫。
signed int m; //聲明了一個帶符號的整數(shù)變量 m
// 等同于
int m; //聲明了一個帶符號的整數(shù)變量 m
舉例2:int 類型也可以不帶正負(fù)號,只表示非負(fù)整數(shù)。這時就必須使用關(guān)鍵字 unsigned 聲明變量。表數(shù)范圍為:0~4294967295
unsigned int a; //聲明了一個不帶符號的整數(shù)變量a,表數(shù)范圍為:0~4294967295
unsigned int 里面的 int 可以省略,所以上面的變量聲明也可以寫成這樣:
unsigned a;
舉例3:
int 類型使用4個字節(jié)表示一個整數(shù),對于小整數(shù),這樣做很浪費(fèi)空間。另一方面,某些場合需要更大的整數(shù),8個字節(jié)還不夠。此時,可以使用short int (簡寫為 short )、long int (簡寫為 long )、long long int (簡寫為 long long )
signed short int a;
signed long int b;
signed long long int c;
默認(rèn)情況下, short 、 long 、 long long 都是帶符號的(signed),即 signed 關(guān)鍵字可以省略。代碼簡寫為:
short a;
long b;
long long c;
它們也可以聲明為不帶符號(unsigned),使得能夠表示的最大值擴(kuò)大一倍。
unsigned short a; //無符號短整型,表數(shù)范圍:0~65535
unsigned long b; //無符號長整型,表數(shù)范圍:0~4294967295
unsigned long long c; //無符號長整型,表數(shù)范圍:0~18446744073709551615
4.1.3 關(guān)于后綴
編譯器將一個整數(shù)字面量指定為 int 類型,但是如果希望將其指定為 long 類型,需要在該字面量末尾加上后綴 l 或 L ,編譯器會把這個字面量的類型指定為 long 。
long x = 123L; //或者寫成 123l
如果希望字面量指定為long long類型,則后綴以ll或LL結(jié)尾。
long long y = 123LL;
如果希望指定為無符號整數(shù) unsigned int ,可以使用后綴 u 或 U 。
unsigned int x = 123U;
L 和 U 可以結(jié)合使用,表示 unsigned long 類型。 L 和 U 的大小寫和組合順序無所謂。
u 還可以與其他整數(shù)后綴結(jié)合,放在前面或后面都可以,比如 10UL 、 10ULL 和 10LLU 都是合法的。
unsigned long int x = 1234UL;
unsigned long long int x = 1234ULL;
4.1.4 精確寬度類型(了解)
C 語言的整數(shù)類型(short、int、long)在不同計算機(jī)上,占用的字節(jié)寬度可能是不一樣的,無法提前知道它們到底占用多少個字節(jié)。程序員有時控制準(zhǔn)確的字節(jié)寬度,這樣的話,代碼可以有更好的可移植性,頭文件 stdint.h 創(chuàng)造了一些新的類型別名。
精確寬度類型(exact-width integer type):保證某個整數(shù)類型的寬度是確定的。
-
int8_t :8位有符號整數(shù)
-
int16_t :16位有符號整數(shù)
-
int32_t :32位有符號整數(shù)
-
int64_t :64位有符號整數(shù)
-
uint8_t :8位無符號整數(shù)
-
uint16_t :16位無符號整數(shù)
-
uint32_t :32位無符號整數(shù)
-
uint64_t :64位無符號整數(shù)
上面這些都是類型別名,編譯器會指定它們指向的底層類型。比如,某個系統(tǒng)中,如果 int 類型為32位, int32_t 就會指向 int ;如果 long 類型為32位, int32_t 則會指向 long 。
#include <stdio.h>
#include <stdint.h>
int main() {
int32_t x32 = 45933945; //變量 x32 聲明為 int32_t 類型,可以保證是32位的寬度。
printf("x32 = %d\n", x32);
return 0;
}
4.1.5 整型的極限值(了解)
有時候需要查看,當(dāng)前系統(tǒng)不同整數(shù)類型的最大值和最小值,C 語言的頭文件 limits.h 提供了相應(yīng)的常量。比如:INT_MIN 代表 signed int 類型的最小值 -2147483648, INT_MAX 代表 signed int 類型的最大值 2147483647。
#include <limits.h>
int main() {
printf("%d\n", INT_MIN ); // -2147483648
printf("%d\n", INT_MAX ); // 2147483647
return 0;
}
為了代碼的可移植性,需要知道某種整數(shù)類型的極限值時,應(yīng)該盡量使用這些常量。
-
SCHAR_MIN , SCHAR_MAX :signed char 的最小值和最大值。
-
SHRT_MIN , SHRT_MAX :short 的最小值和最大值。
-
INT_MIN , INT_MAX :int 的最小值和最大值。
-
LONG_MIN , LONG_MAX :long 的最小值和最大值。
-
LLONG_MIN , LLONG_MAX :long long 的最小值和最大值。
-
UCHAR_MAX :unsigned char 的最大值。
-
USHRT_MAX :unsigned short 的最大值。
-
UINT_MAX :unsigned int 的最大值。
-
ULONG_MAX :unsigned long 的最大值。
-
ULLONG_MAX :unsigned long long 的最大值。
4.2 浮點(diǎn)類型
4.2.1 類型說明
浮點(diǎn)型變量,也稱為實(shí)型變量,用來存儲小數(shù)數(shù)值的。因?yàn)?2位浮點(diǎn)數(shù)提供的精度或者數(shù)值范圍還不夠,C 語言又提供了另外兩種更大的浮點(diǎn)數(shù)類型。
在C語言中,浮點(diǎn)型變量分為三種:單精度浮點(diǎn)型(float)、雙精度浮點(diǎn)型(double)、長雙精度浮點(diǎn)型(long double)。
| 類型 | 占用空間 | 取值范圍 |
|---|---|---|
| float | 4個字節(jié) (=32位) | $-1.410^{-45}$ ~ $-3.410{+38}$,$1.4*10$ ~ $3.4*10^{+38}$ |
| double | 8個字節(jié) (=64位) | $-4.910^{-324}$ ~ $-1.710{+308}$,$4.9*10$ ~ $1.7*10^{+308}$ |
| long double | 12個字節(jié)(=96位) | 太大了... |
其中,
| 類型 | 16位編譯器 | 32位編譯器 | 64位編譯器 |
|---|---|---|---|
| float | 4字節(jié) | 4字節(jié) | 4字節(jié) |
| double | 8字節(jié) | 8字節(jié) | 8字節(jié) |
C語言的第3種浮點(diǎn)類型是long double,以滿足比double類型更高的精度要求。不過,C只保證long double類型至少與double類型的精度相同。
浮點(diǎn)型變量不能使用signed或unsigned修飾符。
最常用的浮點(diǎn)類型為:double 類型,因?yàn)榫缺萬loat高。
浮點(diǎn)型常量,默認(rèn)為 double 類型。
關(guān)于后綴:
對于浮點(diǎn)數(shù),編譯器默認(rèn)指定為 double 類型,如果希望指定為float類型,需要在小數(shù)后面添加后綴 f或F;如果希望指定為long double類型,需要在小數(shù)后面添加后綴 l或L。
float x = 3.14f;
double x = 3.14;
long double x = 3.14L;
4.2.2 舉例
舉例1:
float f = 123.4f; //后面必須加上字母f
double d1 = 101.1; //后面可以省略字母d
double d2 = 299.4; //后面可以加上字母d
舉例2:
C 語言允許使用科學(xué)計數(shù)法表示浮點(diǎn)數(shù),使用字母 e 來分隔小數(shù)部分和指數(shù)部分。注意,e 的前后,不能存在空格。
double x = 123.456e+3; // 123.456 x 10^3
// 等同于
double x = 123.456e3;
另外,科學(xué)計數(shù)法的小數(shù)部分如果是 0.x 或 x.0 的形式,那么 0 可以省略。
0.3E6
// 等同于
.3E6
3.0E6
// 等同于
3.E6
舉例3:可以在常量的末尾加專用字符,強(qiáng)制指定常量的類型
float a = 3.14159f; //把此3.14159按單精度浮點(diǎn)常量處理
long double a = 1.23L; //把此1.23作為long double型處理
舉例4:
有人用溫度計測量出用華氏法表示的溫度(如64°F),今要求把它轉(zhuǎn)換為以攝氏法表示的溫度(如17.8℃)。轉(zhuǎn)換的公式為:$c = \frac{5}{9}(f - 32)$。
其中,f 代表華氏溫度,c 代表攝氏溫度。
#include <stdio.h>
int main() {
float f, c; //定義f和c分別表示華氏溫度、攝氏溫度
f = 64.0; //指定f的值
c = (5.0 / 9) * (f - 32); //利用公式計算c的值
printf("f=%f\nc=%f\n", f, c); //輸出c的值
return 0;
}
4.2.3 存儲規(guī)則(了解)
任何有小數(shù)點(diǎn)的數(shù)值,都會被編譯器解釋為浮點(diǎn)數(shù)。所謂“浮點(diǎn)數(shù)”就是使用 m * b^e 的形式,存儲一個數(shù)值, m 是小數(shù)部分, b 是基數(shù), e 是指數(shù)部分。
從十進(jìn)制的角度:

從二進(jìn)制的角度:
根據(jù)國際標(biāo)準(zhǔn)IEEE(電氣和電子工程協(xié)會) 754,任意一個二進(jìn)制浮點(diǎn)數(shù)V可以表示成下面的形式:$(-1)^S * M * 2^E$
其中:
-
$(-1)^s$表示符號位,當(dāng)s=0,V為正數(shù);當(dāng)s=1,V為負(fù)數(shù)。
-
M表示有效數(shù)字,大于等于1,小于2。
-
$2^E$表示指數(shù)位。
舉例來說:
十進(jìn)制的5.0,寫成二進(jìn)制是 101.0 ,相當(dāng)于 1.01×2^2 。即,按照上面V的格式,可以得出s=0,M=1.01,E=2。
十進(jìn)制的-5.0,寫成二進(jìn)制是 -101.0 ,相當(dāng)于 -1.01×2^2 。即,s=1,M=1.01,E=2。
IEEE 754規(guī)定:
對于32位的浮點(diǎn)數(shù),最高的1位是符號位s,接著的8位是指數(shù)E,剩下的23位為有效數(shù)字M。

對于64位的浮點(diǎn)數(shù),最高的1位是符號位S,接著的11位是指數(shù)E,剩下的52位為有效數(shù)字M。

浮點(diǎn)數(shù)的存儲方式,決定了浮點(diǎn)數(shù)精度控制在一定范圍內(nèi)。有效數(shù)字部分可能丟失,造成精度損失。
4.3 字符類型
C語言中,使用 char 關(guān)鍵字來表示字符型,用于存儲一個單一字符。
字符型變量賦值時,需要用一對英文半角格式的單引號('')把字符括起來。
每個字符變量,在16位、32位或64位編譯器中都是占用 1 個字節(jié)(=8位)。
表示方式1:最常見
char c = 'A'; //為一個char類型的變量賦值字符'A'
每個字符對應(yīng)一個整數(shù)(由 ASCII 碼確定),比如 A 對應(yīng)整數(shù) 65 。
只要在字符類型的范圍之內(nèi),整數(shù)與字符是可以互換的,都可以賦值給字符類型的變量。
表示方式2:ASCII 碼值
char c = 66;
// 等同于
char c = 'B';
兩個字符類型的變量可以進(jìn)行數(shù)學(xué)運(yùn)算。
char a = 'B'; // 等同于 char a = 66;
char b = 'C'; // 等同于 char b = 67;
printf("%d\n", a + b); // 輸出133
常見的ASCII值與對應(yīng)的字符如下:(ASCII數(shù)值范圍為0-127)

ASCII碼:上個世紀(jì)60年代,美國制定了一套字符編碼,對英語字符與二進(jìn)制位之間的關(guān)系,做了統(tǒng)一規(guī)定。這被稱為ASCII碼。ASCII碼一共規(guī)定了127個字符的編碼,比如空格“SPACE”是32(二進(jìn)制00100000),大寫的字母A是65(二進(jìn)制01000001)。這128個符號(包括32個不能打印出來的控制符號),只占用了一個字節(jié)的后面7位,最前面的1位統(tǒng)一規(guī)定為0,也就是說,ASCII雖然用8位二進(jìn)制編碼表示字符,但是其有效位為7位。
舉例1:字符′1′和整數(shù)1是不同的概念。(參看ASCII碼表)
char c1 = 1;
char c2 = '1';
printf("c1 = %d\n",c1); // c1 = 1
printf("c2 = %d\n",c2); // c2 = 49
舉例2:
char c='?'; //定義c為字符型變量并使初值為字符'?'。'?'的ASCII代碼是63,系統(tǒng)把整數(shù)63賦給變量c。
printf("%d %c\n",c,c); //用"%d"格式輸出十進(jìn)制整數(shù)63,用"%c"格式輸出字符'?'
signed 和 unsigned 修飾:
根據(jù)C90標(biāo)準(zhǔn),C語言允許在關(guān)鍵字char前面使用signed或unsigned。
signed char c; // 范圍為 -128 到 127
unsigned char c; // 范圍為 0 到 255
注意,C 語言規(guī)定 char 類型默認(rèn)是否帶有正負(fù)號,由當(dāng)前系統(tǒng)決定,這一點(diǎn)與 int 不同, int 等同于 signed int 。這就是說, char 不等同于signed char ,它有可能是 signed char(范圍-128 到 127) ,也有可能是 unsigned char (范圍0 到255)。不管是哪種,范圍都正好都能覆蓋 0 到 127 的 ASCII 字符范圍。
表示方式3:使用轉(zhuǎn)義字符
單引號本身也是一個字符,如果要表示這個字符常量,必須使用反斜杠轉(zhuǎn)義。
char t = '\'';
char還可以用來表示轉(zhuǎn)義字符。比如:
| 字符形式 | 含義 |
|---|---|
\n |
換行符(光標(biāo)移動到下行行首) |
\t |
水平制表符,光標(biāo)移到下一個Tab位置 |
\' |
單引號字符 ' |
\" |
雙引號字符 " |
\\ |
反斜杠字符 ’\’ |
\r |
回車符,光標(biāo)移到本行開頭 |
\0 |
null 字符,代表沒有內(nèi)容。注意,這個值不等于數(shù)字0。 |
\b |
退格鍵,光標(biāo)回退一個字符,但不刪除字符 |
4.4 布爾類型
C語言標(biāo)準(zhǔn)(C89)沒有為布爾值單獨(dú)設(shè)置一個類型,所以在判斷真假時,使用整數(shù) 0 表示假,所有非0表示真。比如:
int main(){
int handsome = 1;
if (handsome) {
printf("我好帥!\n");
}
return 0;
}
上述做法不直觀,可以借助于C語言的宏定義處理。比如:
// 定義布爾類型的宏
#define BOOL int //可以使用 typedef int BOOL; 替換
#define TRUE 1
#define FALSE 0
int main(){
BOOL handsome = TRUE;
if(handsome){
printf("好帥~");
}
return 0;
}
此外,C99 標(biāo)準(zhǔn)添加了類型 _Bool,表示布爾值,即邏輯值true和false。但是,這個類型的值其實(shí)只是整數(shù)類型的別名,還是使用 0 表示false, 1 表示true,其它非0的值都會被存儲為1。所以_Bool類型實(shí)際上也是一種整數(shù)類型。
#include <stdio.h>
int main() {
_Bool isFlag = 1;
if (isFlag)
printf("你好毒~~\n");
return 0;
}
與此同時,C99還提供了一個頭文件 stdbool.h,文件中定義了bool代表_Bool,并且定義了 true 代表 1 、 false 代表 0 。只要加載這個頭文件,就可以使用 bool 定義布爾值類型,以及 false 和 true 表示真假。
#include <stdio.h>
#include <stdbool.h>
int main() {
bool isFlag = true;
if (isFlag)
printf("你好毒~~\n");
return 0;
}
【武漢科技大學(xué)2019研】
以下選項(xiàng)中不屬于C語言類型的是( )。
A.short int
B.unsigned long int
C.char
D.bool【答案】D
【解析】C語言中沒有bool型,只有C++才有boolean型,也稱bool。C語言中一般用“0”表示“假”,用“1”表示“真”。
【四川大學(xué)2017研】有4個圓塔,圓心分別為(2,2)、(-2,2)、(-2,-2)、(2,-2),圓半徑為1。這4個塔的高度為10m,塔以外無建筑物。今輸入任一點(diǎn)的坐標(biāo),求該點(diǎn)的建筑高度(塔外的高度為零)。
【答案】
N-S圖如圖1所示。
? 圖1 計算某點(diǎn)建筑高度的N-S流程圖
程序如下:#include<stdio.h> int main() { int h = 10; float x1 = 2, y1 = 2, x2 = -2, y2 = -2, x3 = -2, y3 = -2, x4 = 2, y4 = -2; float x, y; //表示隨意選中的一個點(diǎn)的坐標(biāo) float d1, d2, d3, d4; //(x,y)這個點(diǎn)的坐標(biāo)到各個圓心的距離 printf("請輸入一個點(diǎn)(x,y):"); scanf("%f,%f", &x, &y); d1 = (x - x1) * (x - x1) + (y - y1) * (y - y1); //求該點(diǎn)到各中心點(diǎn)距離 d2 = (x - x2) * (x - x2) + (y - y2) * (y - y2); d3 = (x - x3) * (x - x3) + (y - y3) * (y - y3); d4 = (x - x4) * (x - x4) + (y - y4) * (y - y4); if (d1 > 1 && d2 > 1 && d3 > 1 && d4 > 1) //判斷該點(diǎn)是否在塔外 h = 0; printf("該點(diǎn)高度為%d\n", h); return 0; }
5、變量間的運(yùn)算規(guī)則
在C語言編程中,經(jīng)常需要對不同類型的數(shù)據(jù)進(jìn)行運(yùn)算,運(yùn)算前需要先轉(zhuǎn)換為同一類型,再運(yùn)算。為了解決數(shù)據(jù)類型不一致的問題,需要對數(shù)據(jù)的類型進(jìn)行轉(zhuǎn)換。
5.1 隱式類型轉(zhuǎn)換
情況1:窄類型自動轉(zhuǎn)為寬類型
即,系統(tǒng)自動將字節(jié)寬度較小的類型轉(zhuǎn)換為字節(jié)寬度較大的數(shù)據(jù)類型,它是由系統(tǒng)自動轉(zhuǎn)換完成的。
基本數(shù)據(jù)類型的轉(zhuǎn)換規(guī)則如圖所示:

注意:最好避免無符號整數(shù)與有符號整數(shù)的混合運(yùn)算。因?yàn)檫@時 C 語言會自動將 signed int 轉(zhuǎn)為unsigned int ,可能不會得到預(yù)期的結(jié)果。
舉例1:
- 不同的整數(shù)類型混合運(yùn)算時,寬度較小的類型會提升為寬度較大的類型。比如 short 轉(zhuǎn)為 int ,int 轉(zhuǎn)為 long 等。
- 不同的浮點(diǎn)數(shù)類型混合運(yùn)算時,寬度較小的類型轉(zhuǎn)為寬度較大的類型,比如 float 轉(zhuǎn)為double , double 轉(zhuǎn)為 long double 。
float y = 12 * 2; //整數(shù)賦值給浮點(diǎn)數(shù)變量時,會自動轉(zhuǎn)為浮點(diǎn)數(shù)。結(jié)果24.0
//char類型 與 int類型運(yùn)算,會自動提升為 int 。
char c = 10;
int i = 10;
int j = c + i; //ok
short s1 = 10;
int num1 = s1; //ok
double num2 = s1; //ok
int i = 10;
double d1 = 12.3;
double d2 = i + d1; //系統(tǒng)自動將i的類型由int轉(zhuǎn)換為double類型,故i+d1結(jié)果為double類型
double d;
d = 2 + 'A' + 1.5F;
舉例2:
兩個相同類型的整數(shù)運(yùn)算時,或者單個整數(shù)的運(yùn)算,一般來說,運(yùn)算結(jié)果也屬于同一類型。但是有例外,寬度小于 int 的類型,運(yùn)算結(jié)果會自動提升為 int 。
char c1 = 10;
short s1 = 10;
int i1 = c1 + s1; //char類型和short類型的變量運(yùn)算的結(jié)果默認(rèn)為int類型
unsigned char a = 1;
unsigned char b = 255;
unsigned char c = 255;
if ((a - 5) < 0)
do_something();
if ((b + c) > 300)
do_something();
說明:表達(dá)式 a - 5 和 b + c 都會自動轉(zhuǎn)為 int 類型,所以函數(shù) do_something() 會執(zhí)行兩次。
情況2:寬類型賦值給窄類型
字節(jié)寬度較大的類型,賦值給字節(jié)寬度較小的變量時,會發(fā)生類型降級,自動轉(zhuǎn)為后者的類型。這時可能會發(fā)生截值(truncation),系統(tǒng)會自動截去多余的數(shù)據(jù)位,導(dǎo)致精度損失。
這反映了C語言在檢查類型匹配方面不太嚴(yán)格。最好不要養(yǎng)成這樣的習(xí)慣。
舉例1:
double pi = 3.14159;
int i = pi; // i 的值為 3
C編譯器把浮點(diǎn)數(shù)轉(zhuǎn)換成整數(shù)時,會直接丟棄(截斷)小數(shù)部分,而不進(jìn)行四舍五入。
舉例2:
int x = 3.14; //浮點(diǎn)數(shù)賦予整數(shù)變量時,C 語言直接丟棄小數(shù)部分。結(jié)果 3
int cost = 12.99; // double類型的值轉(zhuǎn)為int類型,結(jié)果為:12
float pi = 3.1415926536; // double類型的值轉(zhuǎn)為float類型,結(jié)果為:3.141593
舉例3:
int i = 322;
char ch = i; // ch 的值是 66
圖示:


舉例4:
float f1 = 1.1f; //ok
double d2 = 4.58667435;
f1 = d2; // 出現(xiàn)精度損失 (double -> float )
printf("f1=%.8f", f1); // 期望: 4.58667435
由于存在精度限制,浮點(diǎn)數(shù)只是一個近似值,它的計算是不精確的。
舉例5:
float a = 3.14159; //3.14159為雙精度浮點(diǎn)常量,分配8個字節(jié);a為float變量,分配4個字節(jié)
編譯時系統(tǒng)會發(fā)出警告(warning: truncation from ′const double′ to′float′),提醒用戶注意這種轉(zhuǎn)換可能損失精度。
5.2 強(qiáng)制類型轉(zhuǎn)換
隱式類型轉(zhuǎn)換中的寬類型賦值給窄類型,編譯器是會產(chǎn)生警告的,提示程序存在潛在的隱患。如果非常明確地希望轉(zhuǎn)換數(shù)據(jù)類型,就需要用到強(qiáng)制(或顯式)類型轉(zhuǎn)換。
形式: (類型名稱)(變量、常量或表達(dá)式)
功能:將“變量、常量或表達(dá)式”的運(yùn)算結(jié)果強(qiáng)制轉(zhuǎn)換為“類型名稱”所表示的數(shù)據(jù)類型。
注意:強(qiáng)制類型轉(zhuǎn)換會導(dǎo)致精度損失。
舉例:
double x = 12.3;
int y = 10;
int z = (int)x + y; //將變量x的值轉(zhuǎn)換成int后,再與y相加
將浮點(diǎn)數(shù)轉(zhuǎn)換為整數(shù)時,將舍棄浮點(diǎn)數(shù)的小數(shù)部分,只保留整數(shù)部分。
float f1,f2;
f1 = (int)1.2 + 3.4;
f2 = (int)(1.2 + 3.4);
printf("f1=%f,f2=%f",f1,f2);
輸出結(jié)果:f1=4.4,f2=4.0。
舉例2:
int i = 40000;
short s = (short)i;
printf("%d\n",s); //-25536
舉例3:
long y = (long) 10 + 12; // (long) 將 10 顯式轉(zhuǎn)為 long 類型。這里的顯示轉(zhuǎn)換其實(shí)是不必要的,因?yàn)榭梢宰詣愚D(zhuǎn)換
5.3 運(yùn)算的溢出問題
每一種數(shù)據(jù)類型都有數(shù)值范圍,如果存放的數(shù)值超出了這個范圍(小于最小值或大于最大值),需要更多的二進(jìn)制位存儲,就會發(fā)生溢出。大于最大值,叫做向上溢出(overflow);小于最小值,叫做向下溢出(underflow)。
一般來說,編譯器不會對溢出報錯,會正常執(zhí)行代碼,但是會忽略多出來的二進(jìn)制位,只保留剩下的位,這樣往往會得到意想不到的結(jié)果。所以,應(yīng)該避免溢出。
舉例1:
unsigned char x = 255;
x = x + 1;
printf("%d\n", x); // 0
x 是 unsign char 類型,最大值是255 (二進(jìn)制 11111111 ),加 1 后就發(fā)生了溢出, 256 (二進(jìn)制 100000000 )的最高位 1 被丟棄,剩下的值就是 0 。
舉例2:
unsigned int ui = UINT_MAX; // 4,294,967,295
ui++;
printf("ui = %u\n", ui); // 0
ui--;
printf("ui = %u\n", ui); // 4,294,967,295
常量 UINT_MAX 是 unsigned int 類型的最大值。如果加 1 ,對于該類型就會溢出,從而得到 0 ;而 0 是該類型的最小值,再減 1 ,又會得到 UINT_MAX 。
溢出很容易被忽視,編譯器又不會報錯,所以必須非常小心。
6、常量
6.1 常量分類
程序運(yùn)行時,其值不能改變的量,即為常量。
C語言中的常量分為以下以下幾種:
- 字面常量
- #define 定義的標(biāo)識符常量
- const 修飾的常變量
- 枚舉常量
舉例:字面常量
1、2、12是整型常量,2.1、12.5、3.14是實(shí)型常量,'a'、 'b'、'c'是字符型常量。
#include <stdio.h>
int main(){
//字面常量
3.14;//字面常量
1000;//字面常量
}
6.2 多種方式定義常量
6.2.1 使用#define
這種方式是在文件開頭用 #define 來定義常量,也叫作“宏定義”。所謂宏定義,就是用一個標(biāo)識符來表示一個常量值,如果在后面的代碼中出現(xiàn)了該標(biāo)識符,那么編譯時就全部替換成指定的常量值。即用宏體替換所有宏名,簡稱宏替換。
定義格式:#define 符號常量名 常量值
- 符號常量名,稱為
宏體,屬于標(biāo)識符,一般定義時用大寫字母表示。 - 常量值,稱為
宏名,可以是數(shù)值常量,也可以是字符常量。
習(xí)慣上,宏名用大寫字母表示,以便于與變量區(qū)別。但也允許用小寫字母。
舉例1:
#include <stdio.h>
#define ZERO 0 //#define的標(biāo)識符常量
int main() {
printf("zero = %d\n", ZERO);
return 0;
}
跟#include一樣,“#”開頭的語句都是“預(yù)處理語句”,在編譯之前,預(yù)處理器會查找程序中所有的“ZERO”,并把它替換成0,這個過程稱為預(yù)編譯處理。
然后將預(yù)處理的結(jié)果和源程序一起再進(jìn)行通常的編譯處理,以得到目標(biāo)代碼 (OBJ文件)。
舉例2:
#include <stdio.h>
#define PI = 3.14 // 定義常量 PI,常量值 3.14。因?yàn)楹甓x不是 C 語句,后面不能有分號
int main() {
//PI = 3.1415 可以嗎? => 不可以
double area;
double r = 1.2;
area = PI * r * r;
printf("面積 : %.2f", area);
getchar();
return 0;
}
舉例3:
//函數(shù)結(jié)果狀態(tài)代碼
#define OK 1
#define ERROR 0
#define OVERFLOW -2
define 對于考研數(shù)據(jù)結(jié)構(gòu)來說沒有什么貢獻(xiàn),我們只要認(rèn)得它就行。
例如1,
#define MAX_Size 50這句,即定義了常量MAX_Size(此時x = 50;等價于x = MAX_Size;)。例如2,你要定義一個數(shù)組,如
int A[MAX_Size];,加上一句注釋“/*MAX_Size為已經(jīng)定義的常量,其值為50*/”即可。
6.2.2 使用const限定符
C99中新的聲明方式,這種方式跟定義一個變量是一樣的,只需要在變量的數(shù)據(jù)類型前再加上一個const關(guān)鍵字,這被稱為“限定符”。
格式:
const 數(shù)據(jù)類型 常量名 = 常量值;
舉例:
#include <stdio.h>
int main(){
//const 修飾的常變量
const float PI = 3.14f;
//PI = 5.14;//是不能直接修改的!
return 0;
}
const修飾的對象一旦創(chuàng)建就不能改變,所以必須初始化。
跟使用 #define定義宏常量相比,const定義的常量有詳細(xì)的數(shù)據(jù)類型,而且會在編譯階段進(jìn)行安全檢查,在運(yùn)行時才完成替換,所以會更加安全和方便。
6.3.3 定義枚舉常量
舉例:
#include <stdio.h>
//使用enum定義枚舉類
enum Sex{
//括號中的MALE,FEMALE,SECRET是枚舉常量
MALE,
FEMALE,
SECRET
};
int main(){
//枚舉常量
printf("%d\n", MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
//注:枚舉常量默認(rèn)是從0開始,依次向下遞增1的
return 0;
}
【北京航空航天大學(xué)2018研】若已知有如下宏定義
#define CANBERRA(x,y) ((x-y)/(x+y))則以下表達(dá)式中,返回結(jié)果值最大的是( )。
A.CANBERRA(3.0,2.0);
B.CANBERRA(4.0,1.0);
C.CANBERRA(1.0+2.0,0.0+2.0);
D.CANBERRA(1.0+2.0,1.0+1.0);【答案】C
【解析】A項(xiàng)中為1.0/5.0,結(jié)果為0.2;B項(xiàng)中為3.0/5.0,結(jié)果為0.6;C項(xiàng)中的宏替換后為(1.0+2.0-0.0+2.0)/(1.0+2.0+0+2.0)=1.0;D項(xiàng)中宏替換后為(1.0+2.0-1.0+1.0)/(1.0+2.0+1.0+1.0)=0.6,因此最后答案為C。
【中央財經(jīng)大學(xué)2018研】若有如下宏定義:
#define N 2 #define y(n) ((N+1)*n)則執(zhí)行下列語句:z=4*(N+y(5));后的結(jié)果是( )。
A.語句有錯誤
B.z值為68
C.z值為60
D.z值為180【答案】B
【解析】y(5)=15,z=4*(N+y(5))=4*17=68,答案選B。
7、輸入/輸出函數(shù)
所謂輸入輸出是以計算機(jī)主機(jī)為主體而言的。
- 輸出:從計算機(jī)向外部輸出設(shè)備(顯示器、打印機(jī))輸出數(shù)據(jù)。
- 輸入:從輸入設(shè)備(鍵盤、鼠標(biāo)、掃描儀)向計算機(jī)輸入數(shù)據(jù)。
![image]()
c語言本身沒有提供專門的輸入輸出語句,所有的輸入輸出都是由調(diào)用標(biāo)準(zhǔn)庫函數(shù)中的輸入輸出函數(shù)來實(shí)現(xiàn)的。
輸入函數(shù):scanf() 、 getchar()、gets():
- scanf(),是格式輸入函數(shù),可接收
任意類型的數(shù)據(jù)。 - getchar(),是
字符輸入函數(shù), 只能接收單個字符。 - gets(),是
字符串輸入函數(shù)。
輸出函數(shù):printf() 、 putchar()、puts():
- printf(),是格式輸出函數(shù),可按指定的格式顯示任意類型的數(shù)據(jù)。
- putchar(),
字符顯示函數(shù),只能顯示單個字符。 - puts(),是
字符串輸出函數(shù)。
7.1 scanf()的使用
scanf()函數(shù)的作用:把從鍵盤上輸入的數(shù)據(jù)根據(jù)找到的地址存入內(nèi)存中,即給變量賦值。
格式: scanf("格式控制字符串",參數(shù)地址列表);
- “格式控制字符串”:約定輸入數(shù)據(jù)的類型和格式,參數(shù)的個數(shù)必須與變量地址的個數(shù)一致。
- “參數(shù)地址列表”:以逗號 “, ”分隔的、
輸入數(shù)據(jù)變量地址序列。
舉例:
scanf("%d%d%d",&a,&b,&c)
其中,&a,&b,&c中的&是尋址操作符,&a表示對象a在內(nèi)存中的地址。
注意,
- 如果scanf中%d是連著寫的,如“
%d%d%d”,在輸入數(shù)據(jù)時,數(shù)據(jù)之間不可以用逗號分隔,只能用空白字符(空格或tab鍵或者回車鍵)分隔。即“2(空格)3(tab)4” 或 “2(tab)3(回車)4”等。 - 如果是“
%d,%d,%d”,則在輸入數(shù)據(jù)時需要加“,”,如“2,3,4”。
舉例1:計算圓的面積,其半徑由用戶指定
#include <stdio.h>
int main() {
float radius, area;
printf("請輸入半徑值: ");
scanf("%f", &radius); //輸入半徑
area = 3.14 * radius * radius;
printf("area=%f\n", area); //輸出圓的面積
return 0;
}
注意:變量名之前要加上&運(yùn)算符,表示取變量的地址,如“&a,&b”。否則將會出現(xiàn)錯誤。
舉例2:輸入一個整數(shù),求其絕對值。
#include <stdio.h>
int main() {
int num;
printf("輸入一個整數(shù):");
scanf("%d", &num);
int absNum = num;
if(absNum < 0)
absNum = -absNum;
printf("\n 整數(shù):%d--->絕對值為:%d\n", num, absNum);
return 0;
}
舉例3:輸入多個變量的值,求乘積
#include <stdio.h>
int main() {
int a,b,c;
printf("請輸入整數(shù)a,b:");
scanf("%d%d",&a,&b);
c=a*b;
printf("%d*%d=%d\n",a,b,c);
return 0;
}
【武漢科技大學(xué)2019研】若有聲明語句:int x; char y[20]; double z;則正確的輸入語句是( )。
A.scanf("%d%c%le\n",&x,&y,&z);
B.scanf("%2d%s%lf",&x,&y,&z);
C.scanf("%d%s%lf",&x,y,&z);
D.scanf("%x%s%3.2f",&x,y,&z);【答案】C
【解析】y為一維數(shù)組名,指向數(shù)組首元素的地址,因此不需要再使用取地址運(yùn)算符&,AB錯誤;D中%3.2f表示長度為3,小數(shù)為2位,但是小數(shù)點(diǎn)也占一位,因此D錯誤,答案選C。
7.2 getchar()與putchar()的使用
-
getchar():輸入字符數(shù)據(jù)
- 格式:getchar()
- 功能:從鍵盤緩沖區(qū)讀入一個字符
-
putchar():輸出字符
- 格式: putchar(ch),其中ch是一個字符變量
- 功能:從標(biāo)準(zhǔn)輸出設(shè)備輸出一個字符
舉例:
#include <stdio.h>
int main() {
char c = 0;
putchar('A'); //輸出單個字符A
putchar(c); //輸出變量c的ASCII對應(yīng)字符
putchar('\n'); //執(zhí)行換行效果,屏幕不顯示
}
#include <stdio.h>
int main() {
char ch;
ch = getchar();
putchar(ch);
return 0;
}
7.3 gets()與puts()的使用(超綱)
puts():
在C語言中,puts() 是一個用于輸出字符串的標(biāo)準(zhǔn)庫函數(shù),其原型定義在 <stdio.h> 頭文件中。puts() 函數(shù)的作用是將一個以 null 字符(\0)結(jié)尾的字符串打印到標(biāo)準(zhǔn)輸出(通常是控制臺)上,并自動添加一個換行符。
int main() {
char str1[]={"China\nBeijing"};
char str2[] = "helloworld";
puts(str1);
puts(str2);
return 0;
}
注意,puts()函數(shù)只能用于輸出字符串,而不能輸出其他類型的數(shù)據(jù)。如果需要輸出其他類型的數(shù)據(jù),應(yīng)使用 printf() 函數(shù)。
gets():
讀取標(biāo)準(zhǔn)輸入設(shè)備輸入的字符串,直到遇到【Enter】鍵才結(jié)束。
char str[20]; //定義一個數(shù)組
gets(str); //獲取輸入的字符串,存放到字符數(shù)組中
舉例:字符串的讀寫
int main() {
char str[15];
printf("enter your name:");
gets(str); //輸入字符串至數(shù)組變量str
printf("your name is ");
puts(str); //輸出字符串
return 0;
}
8、變量按聲明位置的分類(后面講)
變量按照聲明的位置,可以分為:局部變量 和 全局變量。
-
局部變量
- 在
函數(shù)體內(nèi)定義的變量,也稱內(nèi)部變量。局部變量只能在定義它的函數(shù)中使用。
- 在
-
全局變量
-
在
函數(shù)之外定義的變量稱為外部變量,外部變量是全局變量(也稱全程變量)。 -
一個程序中,凡是在全局變量之后定義的函數(shù),都可以使用在其之前定義的全局變量。
-
舉例:
#include <stdio.h>
int global = 2023;//全局變量
int main(){
int local = 2022;//局部變量
//下面定義的global會不會報錯?
int global = 2024;//局部變量
printf("global = %d\n", global);
return 0;
}
當(dāng)局部變量和全局變量同名的時候,局部變量優(yōu)先使用。
9、常見的進(jìn)制
9.1 二進(jìn)制概述
計算機(jī)底層如何存儲數(shù)據(jù)呢?
計算機(jī)世界中只有二進(jìn)制,所以計算機(jī)中存儲和運(yùn)算的
所有數(shù)據(jù)都要轉(zhuǎn)為二進(jìn)制。包括數(shù)字、字符、圖片、聲音、視頻等。

世界上有10種人 ,認(rèn)識和不認(rèn)識二進(jìn)制的。
二進(jìn)制的由來
二進(jìn)制,是計算技術(shù)中廣泛采用的一種數(shù)制,由德國數(shù)理哲學(xué)大師萊布尼茨于1679年發(fā)明。
二進(jìn)制數(shù)據(jù)是用0和1兩個數(shù)碼來表示的數(shù)。它的基數(shù)為2,進(jìn)位規(guī)則是“逢二進(jìn)一”。
二進(jìn)制的應(yīng)用
二進(jìn)制廣泛應(yīng)用于我們生活的方方面面。比如,廣泛使用的摩爾斯電碼(Morse Code),它由兩種基本信號組成:短促的點(diǎn)信號“·”,讀“滴”;保持一定時間的長信號“—”,讀“嗒”。然后,組成了26個字母,從而拼寫出相應(yīng)的單詞。

我們偶爾會看到的:SOS,即為:

9.2 進(jìn)制的分類
-
十進(jìn)制(decimal)
- 數(shù)字組成:0-9
- 進(jìn)位規(guī)則:滿十進(jìn)一
- C 語言的整數(shù)默認(rèn)都是十進(jìn)制數(shù)
-
二進(jìn)制(binary)
- 數(shù)字組成:0-1
- 進(jìn)位規(guī)則:滿二進(jìn)一,以
0b或0B開頭
int x = 0b101010; -
八進(jìn)制(octal):很少使用
- 數(shù)字組成:0-7
- 進(jìn)位規(guī)則:滿八進(jìn)一,以數(shù)字
0開頭表示
int a = 012; // 八進(jìn)制,相當(dāng)于十進(jìn)制的10 int b = 017; // 八進(jìn)制,相當(dāng)于十進(jìn)制的15 -
十六進(jìn)制
- 數(shù)字組成:0-9,a-f
- 進(jìn)位規(guī)則:滿十六進(jìn)一,以
0x或0X開頭表示。此處的 a-f 不區(qū)分大小寫
int a = 0x1A2B; // 十六進(jìn)制,相當(dāng)于十進(jìn)制的6699 int b = 0X10; // 十六進(jìn)制,相當(dāng)于十進(jìn)制的16
9.3 進(jìn)制的換算舉例
| 十進(jìn)制 | 二進(jìn)制 | 八進(jìn)制 | 十六進(jìn)制 |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 |
| 2 | 10 | 2 | 2 |
| 3 | 11 | 3 | 3 |
| 4 | 100 | 4 | 4 |
| 5 | 101 | 5 | 5 |
| 6 | 110 | 6 | 6 |
| 7 | 111 | 7 | 7 |
| 8 | 1000 | 10 | 8 |
| 9 | 1001 | 11 | 9 |
| 10 | 1010 | 12 | a或A |
| 11 | 1011 | 13 | b或B |
| 12 | 1100 | 14 | c或C |
| 13 | 1101 | 15 | d或D |
| 14 | 1110 | 16 | e或E |
| 15 | 1111 | 17 | f或F |
| 16 | 10000 | 20 | 10 |
9.4 輸出格式
不同的進(jìn)制只是整數(shù)的書寫方法不同,不會對整數(shù)的實(shí)際存儲方式產(chǎn)生影響。不同進(jìn)制可以混合使用,比如 10 + 015 + 0x20 是一個合法的表達(dá)式。
printf() 的進(jìn)制相關(guān)占位符如下:
-
%d :十進(jìn)制整數(shù)。
-
%o :八進(jìn)制整數(shù)。
-
%x :十六進(jìn)制整數(shù)。
-
%#o :顯示前綴 0 的八進(jìn)制整數(shù)。
-
%#x :顯示前綴 0x 的十六進(jìn)制整數(shù)。
-
%#X :顯示前綴 0X 的十六進(jìn)制整數(shù)。
int x = 100;
printf("dec = %d\n", x); // 100
printf("octal = %o\n", x); // 144
printf("hex = %x\n", x); // 64
printf("octal = %#o\n", x); // 0144
printf("hex = %#x\n", x); // 0x64
printf("hex = %#X\n", x); // 0X64
9.5 進(jìn)制間的轉(zhuǎn)換(了解)
9.5.1 二進(jìn)制如何表示整數(shù)?
-
計算機(jī)數(shù)據(jù)的存儲使用二進(jìn)制
補(bǔ)碼形式存儲,并且最高位是符號位。- 正數(shù):
最高位是0 - 負(fù)數(shù):
最高位是1
- 正數(shù):
-
規(guī)定1:正數(shù)的補(bǔ)碼與反碼、原碼一樣,稱為
三碼合一 -
規(guī)定2:負(fù)數(shù)的補(bǔ)碼與反碼、原碼不一樣:
- 負(fù)數(shù)的
原碼:把十進(jìn)制轉(zhuǎn)為二進(jìn)制,然后最高位設(shè)置為1 - 負(fù)數(shù)的
反碼:在原碼的基礎(chǔ)上,最高位不變,其余位取反(0變1,1變0) - 負(fù)數(shù)的
補(bǔ)碼:反碼+1
- 負(fù)數(shù)的
9.5.2 二進(jìn)制與十進(jìn)制間的轉(zhuǎn)換

二進(jìn)制轉(zhuǎn)十進(jìn)制:權(quán)相加法
針對于一個字節(jié)的數(shù)據(jù)舉例來說:

-
例如:1個字節(jié)(8位)
25 ==> 原碼 0001 1001 ==> 反碼 0001 1001 -->補(bǔ)碼 0001 1001
-25 ==>原碼 1001 1001 ==> 反碼1110 0110 ==>補(bǔ)碼 1110 0111
整數(shù):
正數(shù):25 00000000 00000000 000000000 00011001(原碼)
正數(shù):25 00000000 00000000 000000000 00011001(反碼)
正數(shù):25 00000000 00000000 000000000 00011001(補(bǔ)碼)
負(fù)數(shù):-25 10000000 00000000 000000000 00011001(原碼)
負(fù)數(shù):-25 11111111 11111111 111111111 11100110(反碼)
負(fù)數(shù):-25 11111111 11111111 111111111 11100111(補(bǔ)碼)
一個字節(jié)可以存儲的整數(shù)范圍是多少?
//1個字節(jié):8位
0000 0001 ~ 0111 111 ==> 1~127
1000 0001 ~ 1111 1111 ==> -127 ~ -1
0000 0000 ==>0
1000 0000 ==> -128(特殊規(guī)定)=-127-1
十進(jìn)制轉(zhuǎn)二進(jìn)制
十進(jìn)制轉(zhuǎn)二進(jìn)制:除2取余的逆

9.5.3 二進(jìn)制與八進(jìn)制、十六進(jìn)制間的轉(zhuǎn)換
二進(jìn)制轉(zhuǎn)八進(jìn)制

二進(jìn)制轉(zhuǎn)十六進(jìn)制

八進(jìn)制、十六進(jìn)制轉(zhuǎn)二進(jìn)制


練習(xí):以下敘述中錯誤的是( )。
A.C程序在運(yùn)行過程中所有計算都以十進(jìn)制方式進(jìn)行
B.C程序在運(yùn)行過程中所有計算都以二進(jìn)制方式進(jìn)行
C.所有C程序都需要編譯鏈接無誤后才能運(yùn)行
D.C程序中字符變量存放的是字符的ASCII值【答案】A
【解析】C程序在運(yùn)行過程中所有計算都以二進(jìn)制方式進(jìn)行。答案選擇A選項(xiàng)。
【華南理工大學(xué)2018研】與十進(jìn)制1100等值的十六進(jìn)制數(shù)是( )。
A.44A
B.44C
C.54A
D.54C【答案】B
【解析】1100轉(zhuǎn)換成二進(jìn)制為0100 0100 1100,因此轉(zhuǎn)換為十六進(jìn)制為44C。




浙公網(wǎng)安備 33010602011771號