C 語言從回憶到重識 -- 1基礎知識
資料來源:《C Primer Plus 6》
基礎知識
發明者
- Dennis Ritch
- Ken Thompson
C 語言標準
- 最初:K&R C
- 第一個 ANSI/ISO C 標準:ANSI C (即 C89)
- 國際化標準組織與1990年採用了這套 C 標準(ISO C 即 C90),ISO C 和 ANSI C 是完全相同的標準;
- 信任程序員
- 不要妨礙程序員做需要做的事
- 保持語言精練簡單
- 只提供一種方法執行一項操作
- 讓程序運行更快,即使不能保證其可移植性
- 國際化標準組織與1990年採用了這套 C 標準(ISO C 即 C90),ISO C 和 ANSI C 是完全相同的標準;
- C99 標準
- ANSI/ISO 聯合委員會最終於 1999 年發佈
- 遵循最初 C90 標準
- 支持國際化編程
- 彌補缺陷
- 提高計算的實用性
- C11 標準
- 2011 年發佈
C 語言是編譯型語言;
使用步驟
- 定義程序目標
- 設計程序
- 編寫代碼
- 編譯
- 運行程序
- 測試和調試程序
- 維護和修改程序
C 語言是可移植性語言;
helloC.c
#include <stdio.h>
int main(void) {
printf("你好");
return 0;
}
鏈接器
在 C 語言中,所有變量必須先聲明才能使用;
關鍵字和保留標識符
- K&R
- auto
- break
- case
- char
- continue
- default
- do
- double
- else
- extern
- float
- for
- goto
- if
- int
- long
- register
- restrict
- return
- short
- sizeof
- static
- struct
- switch
- typedef
- union
- unsigned
- void
- while
- C90
- signed
- enum
- volatile
- C99
- inline
- C11
- _Alignas
- _Alignof
- _Atomic
- _Bool
- _Complex
- _Generic
- _Imaginary
- _Noreturn
- _Static_assert
- _Thread_local
數據和C
- 常量 constant
- 變量 variable
數據類型
- K&R
- int
- long
- short
- unsigned
- char 存儲字符(字母或標點 即 ASCII 碼)
- float %f %.2f
- double %f、%e(科學計數法)
- C90
- signed
- void
- C99
- _Bool true false
- _Complex 複數
- _Imaginary 虛數
以上除 void 外,均爲基本數據類型;
數據類型組合
- short int
- long int
- long long int (C99)
- long long (C99)
- long double
- unsigned 無符號
- unsigned int (C90)
- unsigned long int (C90)
- unsigned long (C90)
- unsigned short (C90)
- unsigned long long int (C99)
- unsigned long long (C99)
轉義字符
指針 pointer (前綴 & ),
scanf(”%d“, &value);
類型大小:
printf("size is %zd \n", sizeof(long));
sizeof 爲內置運算符;
字符串
strlen 函數
#include <stdio.h>
#include <string.h>
void testChar(void) {
char name[40];
int size, letters;
printf("please input:");
scanf("%s", name);
size = sizeof name;
letters = strlen(name);
printf("name is %s , sizeof is %d , strlen is %d \n", name, size, letters);
}
// name is hello , sizeof is 40 , strlen is 5
注意:name 沒有使用前綴 & ;但如果輸入的是 int 型的變量則需要加 & 前綴,因爲 name 是 char 數組的名稱,本身就是地址索引;
注意:scanf() 讀取字符串時只能讀取一個單詞,若需要讀取一個完整的句子,可以使用 fgets() 函數;
預處理器指令 #define
- 用於定義常量,值不可改變;
- 編譯程序時,會統一替換:
compile-time substitution
- 格式 :
#define NAME value
#define PI 3.1415926
void testDefine(void) {
float area = 3 * 3 * PI;
printf("PI is %.2f", area);
}
字符串
- 字符串本質上是 char 數組
- 包裹在雙引號 ”“ 之間
- 以空字符
'\0'
結尾(空字符 \0 是非打印字符,其 ASCII 碼爲 0)- 例如字符串 ”a“ ,其本質是由兩個 char 組成 :‘a’、’\0’
#include <stdio.h>
#include <string.h>
#define HELLO "hello"
void testLength(void) {
printf("string is %s , sizeof is %lu , strlen is %lu \n", HELLO, sizeof(HELLO), strlen(HELLO));
}
// string is hello , sizeof is 6 , strlen is 5
即 sizeof 的長度包含 ‘\0’ ;
const 限定符
- C90 標準新增的關鍵字,用於限定一個變量爲只讀;
const int MONTHS = 12; // 在程序中不可更改
limits.h
和float.h
頭文件中包含一些常用的 明示常量
I/O 函數
- printf()
- scanf()
長字符串
printf("這是一個"
"長句子\n");
運算符和表達式
運算符
- 賦值運算符 =
- 加法運算符 +
- 減法運算符 -
- 符號運算法
-
- 乘法運算符 *
- 除法運算符 /
- sizeof 運算符和 size_t 類型
- C 語言規定,sizeof 返回 size_t 類型的值(這是一個無符號整數類型)
- 求模運算符 %
- 遞增運算符 ++
- 遞減運算符 –
- 相等運算符 ==
typedef int 別名;
別名 x = 2;
表達式和語句
表達式 由運算符和運算對象組成;
強制類型轉換
long x = 2L;
int mice = (int)1.6 + (int)x;
理論情況下,應該避免自動類型轉換,尤其是類型降級(導致精度失真);
循環
- for
- while
- do while
關係運算符
- <
- <=
>
>=
- ==
- !=
while
void testWhile(int x) {
int i = 0, sum = 0;
while (i < x) {
sum = sum + i;
i++;
}
printf("1 + ... + n = %d (n = %d) \n", sum, x);
}
在 C 中,所有非零視爲
真
,只有 0 被視爲假
;
C99 新增類型 _Bool 類型表示真假;(C99 還提供了stdool.h ,該頭文件讓 bool 定義爲 _Bool 的別稱);
優先級
for
void testFor(int x) {
int i, sum = 0;
for (i = 0; i <= x; i++) {
sum = sum + i;
}
printf("1 + ... + n = %d (n = %d) \n", sum, x);
}
其它賦值運算符
- +=
- -=
- *=
- /=
- %=
出口條件循環 do while
字符數組和字符串
分支和跳轉
關鍵字
- if else
- switch case default
- continue
- break
- goto
if else
int testIfelse(int x) {
if (x >= 60) {
return x;
} else if (x >= 30) {
return x / 2;
} else {
return 0;
}
}
putchar
#include <stdio.h>
#define SPACE ' '
void putcharTest(void) {
char ch = getchar();
while (ch != '\n') {
if (ch == SPACE) {
putchar(ch);
} else {
putchar(ch + 1);
}
ch = getchar();
}
putchar(ch);
}
ctype.h 字符函數
邏輯運算符
- &&
- ||
- !
iso646.h
可以用 and
代替 &&
, or
代替 ||
, not
代替 !
;
#include <iso646.h>
int testIso646(int x) {
if (x % 2 == 0 and x % 3 == 0) {
return x;
}
if (x / 5 == 0 or x / 7 == 0) {
return x;
}
if (not x / 100 == 0) {
return x;
}
return 0;
}
優先級
a > b && b > c || b > d 相當於 ((a > b)&&(b > c)) || (b > d)
?= (三目運算符)
int test1(int x) {
return x < 0 ? -x : x;
}
continue break
- continue 繼續循環 (只能用於循環中)
- break 退出執行 (可用於循環和 switch 語句中)
switch case default
void testSwitch(int x) {
switch (x) {
case 0:
printf("%d", x);
case 1:
printf("%d", x);
break;
case 2:
case 3:
case 4:
printf("x>1 --> %d", x);
default:
printf("not print");
}
}
goto
goto 語句在 C 中仍然可用,但是 C 不用 goto 語句也能運行良好;K&R 提到 goto 語句 易被濫用
,並建議謹慎使用,或者根本不用
;
void testGoto(int x) {
int flag, bill;
if (x > 12)
goto a;
goto b;
a:
x = x * 1.05;
flag = 2;
b:
bill = x * flag;
}
字符輸入輸出和輸入驗證
略