C語言基本知識點
太久沒寫C,就容易忘,很容易和其他語言的語法混淆,故整理一篇C語言的基本知識點。
文章目錄
C程式結構
C 程式主要包括以下部分:
- 前處理器指令
- 函式
- 變數
- 語句 & 表示式
- 註釋
以下是一個例子
#include <stdio.h>
int main()
{
/* 我的第一個 C 程式 \*/
return 0;
}
資料型別
整數型別
char 1 位元組 -128 到 127 或 0 到 255
unsigned char 1 位元組 0 到 255
signed char 1 位元組 -128 到 127
int 2 或 4 位元組 -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647
unsigned int 2 或 4 位元組 0 到 65,535 或 0 到 4,294,967,295
short 2 位元組 -32,768 到 32,767
unsigned short 2 位元組 0 到 65,535
long 4 位元組 -2,147,483,648 到 2,147,483,647
unsigned long 4 位元組 0 到 4,294,967,295
浮點型別
float 4 位元組 1.2E-38 到 3.4E+38 6 位小數
double 8 位元組 2.3E-308 到 1.7E+308 15 位小數
long double 16 位元組 3.4E-4932 到 1.1E+4932 19 位小數
變數和常量
變數
int a;//宣告,也是定義,是需要建立儲存空間的
extern int a; //只是宣告,不是定義。不需要建立儲存空間的,說明變數a可以在別的檔案中定義
常量
在 C 中,有兩種簡單的定義常量的方式:
使用 #define 前處理器。#define LENGTH 10
使用 const 關鍵字。const int LENGTH = 10;
左值和右值
C 中有兩種型別的表示式:
左值(lvalue):指向記憶體位置的表示式被稱為左值(lvalue)表示式。左值可以出現在賦值號的左邊或右邊。
右值(rvalue):術語右值(rvalue)指的是儲存在記憶體中某些地址的數值。右值是不能對其進行賦值的表示式,也就是說,右值可以出現在賦值號的右邊,但不能出現在賦值號的左邊。
C儲存類
儲存類定義 C 程式中變數/函式的範圍(可見性)和生命週期。這些說明符放置在它們所修飾的型別之前。
- auto,是所有區域性變數預設的儲存類。
- register,儲在暫存器中而不是 RAM 中的區域性變數
- static,指示編譯器在程式的生命週期內保持區域性變數的存在,而不需要在每次它進入和離開作用域時進行建立和銷燬。因此,使用 static 修飾區域性變數可以在函式呼叫之間保持區域性變數的值。
- extern,extern 儲存類用於提供一個全域性變數的引用,全域性變數對所有的程式檔案都是可見的。當您使用 ‘extern’ 時,對於無法初始化的變數,會把變數名指向一個之前定義過的儲存位置。當您有多個檔案且定義了一個可以在其他檔案中使用的全域性變數或函式時,可以在其他檔案中使用 extern 來得到已定義的變數或函式的引用。可以這麼理,extern 是用來在另一個檔案中宣告一個全域性變數或函式。extern 修飾符通常用於當有兩個或多個檔案共享相同的全域性變數或函式的時候
運算子
- 算術運算子,略
- 關係運算符,與&&,或||,非!
- 位運算子,&與,|或,~取反,^異或,>>右移
- 賦值運算子,略
- 雜項運算子,sizeof & 三元
- 運算子優先順序,略
條件語句
- if else
- switch
switch(表示式)
{
case 常量表達式1:語句1;[break];
case 常量表達式2:語句2;[break];
...
default:語句n+1;[break];
}
迴圈語句
略
函式
- 函式宣告告訴編譯器函式的名稱、返回型別和引數。函式定義提供了函式的實際主體。
- 函式宣告一般寫在.h檔案中,然後在具體的.c檔案中include該.h後定義函式
- 函式引數:傳值呼叫,引用呼叫
作用域
任何一種程式設計中,作用域是程式中定義的變數所存在的區域,超過該區域變數就不能被訪問。C 語言中有三個地方可以宣告變數:
- 在函式或塊內部的區域性變數
它們只能被該函式或該程式碼塊內部的語句使用。區域性變數在函式外部是不可知的。 - 在所有函式外部的全域性變數
全域性變數在整個程式生命週期內都是有效的,在任意的函式內部能訪問全域性變數。
全域性變數可以被任何函式訪問。也就是說,全域性變數在聲明後整個程式中都是可用的。 - 在形式引數的函式引數定義中
被當作該函式內的區域性變數,它們會優先覆蓋全域性變數
關於初始化區域性變數和全域性變數:當局部變數被定義時,系統不會對其初始化,您必須自行對其初始化。定義全域性變數時,系統會自動對其初始化
陣列
- 宣告陣列:int arr[10];
- 初始化陣列:可以在宣告陣列時進行初始化,int arr[4] = {1,2,3,4};或int arr[]={1,2,3,4};
- 初始化一個全0陣列,int[4] = 0;
- 多維陣列
- 傳遞陣列給函式
- 從函式返回陣列
- 指向陣列的指標
字串
在 C 語言中,字串實際上是使用 null 字元 ‘\0’ 終止的一維字元陣列。因此,一個以 null 結尾的字串,包含了組成字串的字元。
char greeting[] = “Hello”;
C指標
- 宣告 type *var-name;
- 賦值:type *var-name = &var-name2
- 在變數宣告的時候,如果沒有確切的地址可以賦值,為指標變數賦一個 NULL 值是一個良好的程式設計習慣
- 指標陣列:定義用來儲存指標的陣列。
int i, *ptr[MAX];
for ( i = 0; i < MAX; i++)
{
ptr[i] = &var[i]; /* 賦值為整數的地址 */
}
- 指向指標的指標
- 傳遞指標給函式
#include <stdio.h>
#include <time.h>
void getSeconds(unsigned long *par);
int main ()
{
unsigned long sec;
getSeconds( &sec );
/* 輸出實際值 */
printf("Number of seconds: %ld\n", sec );
return 0;
}
void getSeconds(unsigned long *par)
{
/* 獲取當前的秒數 */
*par = time( NULL );
return;
}
- 從函式返回指標
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
/* 要生成和返回隨機數的函式 */
int * getRandom( )
{
static int r[10];
int i;
/* 設定種子 */
srand( (unsigned)time( NULL ) );
for ( i = 0; i < 10; ++i)
{
r[i] = rand();
printf("%d\n", r[i] );
}
return r;
}
/* 要呼叫上面定義函式的主函式 */
int main ()
{
/* 一個指向整數的指標 */
int *p;
int i;
p = getRandom();
for ( i = 0; i < 10; i++ )
{
printf("*(p + [%d]) : %d\n", i, *(p + i) );
}
return 0;
}
- 函式指標
函式指標是指向函式的指標變數。
函式指標可以像一般函式一樣,用於呼叫函式、傳遞引數。
函式指標作為某個函式的引數
函式指標變數可以作為某個函式的引數來使用的,回撥函式就是一個通過函式指標呼叫的函式。
簡單講:回撥函式是由別人的函式執行時呼叫你實現的函式。
函式指標變數的宣告:
typedef int (*fun_ptr)(int,int); // 宣告一個指向同樣引數、返回值的函式指標型別
#include <stdio.h>
int max(int x, int y)
{
return x > y ? x : y;
}
int main(void)
{
/* p 是函式指標 */
int (* p)(int, int) = & max; // &可以省略
int a, b, c, d;
printf("請輸入三個數字:");
scanf("%d %d %d", & a, & b, & c);
/* 與直接呼叫函式等價,d = max(max(a, b), c) */
d = p(p(a, b), c);
printf("最大的數字是: %d\n", d);
return 0;
}
自定義資料型別
enum(列舉)
結構體
共用體
位域
注意事項
- 語句結尾有分號
C99與C11
待寫。。。