C语言指针

目录
  1. 一、指针变量定义
  2. 二、指针重新赋值
  3. 三、指针数组
  4. 四、指针与字符串
  5. 五、指针数组
  6. 六、结构体指针
  7. 七、结构体数组
  8. 八、结构体指针为函数参数
  9. 九、函数指针定义
  10. 十、函数指针回调函数
  11. 十一、用函数指针回调函数的案例
    1. 在Student.h文件里
    2. main.m主函数文件
    3. Student.h 文件
    4. Student.m 文件实现.h里声明的函数

一、指针变量定义

1
int *p = NULL;  // p 为变量名,NULL初始值,NULL恒等于0。

与普通变量不同的是,定义指针变量的时候,前面需要加 * 。

1
2
int a = 3;
int *p = &a; // 指针取地址

二、指针重新赋值

1
*p = 100;   // (*p) 代表 a,p代表a的地址

三、指针数组

1
int arr[3] = {1,3,8};

在C语言中,数组是构造类型,系统会分配一段连续的空间来存储数组的全部数据。其中数组名代表数组首元素地址(第一个元素的内存地址)。

arr 恒等于 &arr[0]。

1
int *p = arr; // 保存数组首地址  此时p与arr相同,均指向数组的首地址。

p[1] = 3;
恒等于arr[1]
恒等于*(p+1)
恒等于*(arr+1)

四、指针与字符串

1
2
char string[] = "iPhone";
char *p = string;

五、指针数组

1
char *strings[3] = {"iPhone", "Android", "win8"};

注意可以通过指针来修改字符数组,但不可以修改字符串。修改用strcopy。

六、结构体指针

定义一个结构体

1
2
3
4
typedef struct {
char name[20];
char sex;
} Student;

结构体指针定义

1
2
3
4
5
6
7
8
9
Student stu = {"Ellen", 'f'};
Student *p = &stu;

// 修改
(*p).sex = 'm';
p->sex = 'm';

// 访问
printf("%c\n", p->sex);

七、结构体数组

1
2
3
4
5
6
7
8
9
Student stus[3] = {
{"Ellen", 'f'},
{"Albert", 'm'}
};

Student *p = stus;
for(int i = 0, i < 3, i++){
printf("%c ", (p+i)->sex);
}

八、结构体指针为函数参数

1
void printStudents(const Student *pStu, int count);

九、函数指针定义

1
2
3
4
5
6
7
8
int maxValue(int a, int b)
{
return a > b ? a : b
}

int (*p)(int a, int b) = NULL;
p = maxValue; // 赋值函数名
int m = p(3,5); // 指针可当函数用

十、函数指针回调函数

1
2
3
4
int getValue(int a, int b, int (*p)(int,int))
{
return p(a, b);
}

函数指针做getValue函数的参数

1
int value = getValue(3,5, maxValue);

十一、用函数指针回调函数的案例

新建 Student.h 和 Student.m 文件

在Student.h文件里

1
2
3
4
5
6
// 声明一个学生结构体
typedef struct {
char name[30]; // 名字
int age; // 年龄
float score; // 成绩
} Student;

main.m主函数文件

1
2
3
4
5
6
7
8
9
10
11
12
13
// 目标是对学生数组的名字或者年龄或者成绩排序
// 用回调指针函数排序
Student stus[] = {
{"Ellen2", 23, 88},
{"Ellen1", 20, 99},
{"Ellen4", 18, 77},
{"Ellen3", 22, 66}
};

int count = sizeof(stus) / sizeof(*stus);
// 实现下面的函数
sortArray(stus, count, "score");
printArray(stus, count);

如何完成上面的目标?

Student.h 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <string.h>
#include <stdbool.h>

// 比较名字
bool compareName(const Student *pStu1, const Student *pStu2);
// 比较年龄
bool compareAge(const Student *pStu1, const Student *pStu2);
// 比较成绩
bool compareScore(const Student *pStu1, const Student *pStu2);
// 定义一个指针函数
typedef bool (*PFUNC)(const Student *, const Student *);
// 声明一个函数名结构体
typedef struct{
char name[20]; // 函数名
PFUNC p; // 指针函数
} FuncName;
// 交换位置
void swap(Student *pStu1, Student *pStu2);
// 冒泡排序
void bubbleSort(Student *pArr, const int count, PFUNC p);
// 根据传入的参数,返回哪种函数
PFUNC getFuncName(const char *pName);
// 排序,pName 传入参数,选择根据XX排序
void sortArray(Student *pArr, const int count, const char *pName);
// 遍历数组
void printArray(const Student *pArr, const int count);

Student.m 文件实现.h里声明的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// 比较名字
bool compareName(const Student *pStu1, const Student *pStu2)
{
return strcmp(pStu1->name, pStu2->name) > 0;
}
// 比较年龄
bool compareAge(const Student *pStu1, const Student *pStu2)
{
return pStu1->age > pStu2->age;
}
// 比较成绩
bool compareScore(const Student *pStu1, const Student *pStu2)
{
return pStu1->score > pStu2->score;
}
// 交换位置
void swap(Student *pStu1, Student *pStu2)
{
Student temp = *pStu1;
*pStu1 = *pStu2;
*pStu2 = temp;
}
// 冒泡排序
void bubbleSort(Student *pArr, const int count, PFUNC p)
{
for (int i = 0; i < count; i++) {
for (int j = 0; j < count - i - 1; j++) {
if (p(pArr + j, pArr + j + 1)) {
swap(pArr + j, pArr + j + 1);
}
}
}
}
// 根据传入的参数,返回哪种函数
PFUNC getFuncName(const char *pName)
{
FuncName funcNames[] = {
{"name", compareName},
{"age", compareAge},
{"score", compareScore}
};
PFUNC p = NULL;
for (int i = 0; i < sizeof(funcNames) / sizeof(*funcNames); i++) {
if (strcmp(funcNames[i].name, pName) == 0) {
p = funcNames[i].p;
break;
}
}
return p;
}
// 排序,pName 传入参数,选择根据XX排序
void sortArray(Student *pArr, const int count, const char *pName)
{
PFUNC p = NULL;
p = getFuncName(pName);
if (p != NULL) {
bubbleSort(pArr, count, p);
}else{
printf("函数名输入错误!\n");
}
}
// 遍历数组
void printArray(const Student *pArr, const int count)
{
for (int i = 0; i < count; i++) {
printf("%s %d %.2f\n", pArr[i].name, pArr[i].age, pArr[i].score);
}
}

main.m主函数文件只需要指定,根据XX排序,就可以了。

比如按照 年龄 排序

1
sortArray(stus, count, "age");