目錄
九、指針
1.指針變量的定義和初始化
2.間接尋址符*
?3.按值調用和按址調用
4.實例
5.函數指針
6.指針變量和其它類型變量的對比
十、字符串
1.字符串常量
2.字符串的存儲
3.字符指針
4.字符串的訪問和輸入/輸出
5.字符串處理函數
(1)strlen(計算字符串長度)
(2)strcpy(字符串復制)
(3)?strcat(字符串連接)
(4)strcmp(字符串比較)
?(5)實例
(6)其它函數
6.向函數傳遞字符串
7.自己實現字符串處理函數
(1)MyStrcpy
(2)MyStrlen?
(3)MyStrcat?
十一、?指針和數組
1.指針和一維數組的關系
2.指針和二維數組的關系
3.指針或數組參數傳參注意
4.指針數組
gets和puts的使用
5.指針數組用來表示命令行參數
6.C程序的內存映像
7.動態內存分配函數
十二、結構體
1.結構體類型的聲明
2.結構體變量的定義
3.用typedef定義數據類型
4.結構體變量的初始化
5.嵌套的結構體
6.結構體變量的引用?
7.結構體所占內存的字節數
8.結構體數組的定義和初始化
9.結構體指針的定義和初始化
10.向函數傳遞結構體
十三、共用體?
?十四、枚舉數據類型
九、指針
1.指針變量的定義和初始化
指針變量使用之前必須初始化
?2.間接尋址符*
引用指針所指向的變量的值稱為指針的解引用
?3.按值調用和按址調用
指針變量作函數參數可以修改實參的值
4.實例
?
當函數需要給回主函數兩個或兩個以上參數時,無法使用return返回值進行返回,就可以采用指針變量傳參的方式
5.函數指針
?使用函數指針
?
?6.指針變量和其它類型變量的對比
十、字符串
1.字符串常量
2.字符串的存儲?
3.字符指針
?4.字符串的訪問和輸入/輸出
?
對于scanf來說,空格、回車或制表(Tab)符是輸入數據的分隔符,因而不能被讀入,輸入遇到這些字符時,系統認為字符串輸入結束?
例如:
?
fgets()
函數的最大讀取大小是其“第二個參數減1
”,這是由于字符串是以’\0’
為結束符的,fgets()
為了保證輸入內容的字符串格式
,當輸入的數據大小超過了第二個參數
指定的大小的時候,fgets()
會僅僅讀取前面的“第二個參數減1
”個字符,而預留1個字符
的空間來存儲字符串結束符’\0’
5.字符串處理函數
(1)strlen(計算字符串長度)
結果是5?
(2)strcpy(字符串復制)
?
(3)?strcat(字符串連接)
(4)strcmp(字符串比較)
?(5)實例
(6)其它函數
6.向函數傳遞字符串
?7.自己實現字符串處理函數
(1)MyStrcpy
(2)MyStrlen?
(3)MyStrcat?
?
十一、?指針和數組
1.指針和一維數組的關系
數組名是一個常量指針,不能修改該指針的指向
指針可當數組名使用
2.指針和二維數組的關系
行地址?
?
列地址?
行指針?
列指針?
?二維數組傳入函數
?
?3.指針或數組參數傳參注意
4.指針數組
gets和puts的使用
1、gets() 的作用是從鍵盤上讀取字符串,跟scanf() 相似,但又有所不同。
gets() 函數的用法:
gets(字符串的首地址);
例:
char str [20]; .
gets(str);
須要注意的是:
(1) gets() 可以接收空格、Tab鍵, 碰到回車鍵輸入才結束;而scanf碰到空格、回車、Tab鍵 都會結束輸入。
(2) gets() 和scanf() 都不能檢測越界。
2、puts() 的作用是 向顯示屏輸出字符串并換行。
用法:
puts (字符串的首地址) ;
例:
char[]=" helloworld";
pus(str);
printf需要添加"\n'用來換行,而puts在 輸出的時候會將字符串末尾的\0'自動換成\n'
5.指針數組用來表示命令行參數
?
6.C程序的內存映像
?7.動態內存分配函數
?
malloc()?
?calloc
注意?:int (*p)[3]和int *p[3]的區別如下:
1. 聲明的含義
-
int (*p)[3]:
- 這是一個指針,指向一個包含 3 個?
int
?元素的數組。 p
?是一個指針,它所指向的數據類型是?int[3]
(一個有 3 個?int
?元素的數組)。
- 這是一個指針,指向一個包含 3 個?
-
int *p[3]:
- 這是一個數組,數組的元素是?
int
?類型的指針。 p
?是一個數組,該數組包含 3 個元素,每個元素的類型是?int*
(指向?int
?的指針)。
- 這是一個數組,數組的元素是?
2. 內存布局和使用示例
-
int (*p)[3]:
-
#include <stdio.h> int main() {int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};int (*p)[3]; // 定義一個指針,指向一個包含 3 個 int 元素的數組p = arr; // 讓 p 指向 arr 的第一行// 訪問元素for (int i = 0; i < 2; ++i) {for (int j = 0; j < 3; ++j) {printf("%d ", (*p)[j]); // 先解引用 p 得到數組,再通過 [] 訪問元素}p++; // 指向下一個 3 元素的數組}return 0; }
- 在這個例子中,
p
?是一個指針,它可以指向一個?int[3]
?類型的數組。當我們將?p
?指向?arr
?的第一行時,通過?(*p)[j]
?來訪問元素。p++
?操作會讓?p
?指向下一個包含 3 個?int
?的數組(在二維數組中,即下一行)。
int *p[3]:
#include <stdio.h>
int main() {int a = 1, b = 2, c = 3;int *p[3]; // 定義一個數組,元素是 int 指針p[0] = &a;p[1] = &b;p[2] = &c;// 訪問元素for (int i = 0; i < 3; ++i) {printf("%d ", *(p[i])); // 先通過 [] 獲取指針,再解引用}return 0;
}
- 這里?
p
?是一個數組,存儲了 3 個?int
?指針。p[0]
、p[1]
?和?p[2]
?分別存儲了?a
、b
?和?c
?的地址,通過?*(p[i])
?來訪問它們指向的?int
?元素。
3. 指針運算和內存地址
-
int (*p)[3]:
- 當對?
p
?進行指針運算(如?p++
)時,p
?的地址會增加?3 * sizeof(int)
,因為它指向的是一個包含 3 個?int
?元素的數組,每次移動到下一個這樣的數組。
- 當對?
-
int *p[3]:
- 對于?
p[i]
(其中?i
?從 0 到 2),p[i]
?是?int*
?指針,當對?p[i]
?進行指針運算時,其地址會增加?sizeof(int)
,因為它們指向的是單個?int
?元素。
- 對于?
4. 總結
int (*p)[3]
?強調的是一個指針,該指針專門指向包含 3 個?int
?元素的數組,適合用于處理二維數組,其中第二維大小固定為 3。int *p[3]
?是一個數組,其中存儲的元素是?int
?指針,可存儲 3 個不同?int
?變量的地址,可指向不同位置的?int
?元素,使用更靈活,可指向不同長度的?int
?數組或不同的?int
?元素。
十二、結構體
1.結構體類型的聲明
這時還沒有聲明結構體變量?
2.結構體變量的定義
3.用typedef定義數據類型
?4.結構體變量的初始化
5.嵌套的結構體
6.結構體變量的引用?
7.結構體所占內存的字節數
8.結構體數組的定義和初始化
?
9.結構體指針的定義和初始化
?
10.向函數傳遞結構體
?
?
例題
?
十三、共用體?
?