目录
## 重点掌握
1、数组
2、指针
3、结构体
4、函数
回调函数的常见用途
## 如何区分数组指针,指针数组,函数指针,结构体指针,指针偏移量
## 重点掌握
1、数组
https://blog.csdn.net/weixin_60546365/article/details/146476765
重点注意:
①数组逆置操作:
#include <stdio.h>int main() {// 定义一个数组,同时初始化所有成员变量int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int i = 0; // 首元素下标int j = sizeof(a) / sizeof(a[0]) - 1; // 尾元素下标int temp;while (i < j) {// 元素交换值temp = a[i];a[i] = a[j];a[j] = temp;// 位置移动i++;j--;}for (i = 0; i < sizeof(a) / sizeof(a[0]); i++) {printf("%d, ", a[i]);}return 0;
}
②数组与指针
#include <stdio.h>int main() {int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};int i = 0;int n = sizeof(a) / sizeof(a[0]);for (i = 0; i < n; i++) {// * 和 [] 效果一样,都是操作指针所指向的内存// printf("%d, ", a[i]);printf("%d, ", *(a + i)); //a+i参考指针步长}printf("\n");// 定义一个指针变量保存a的地址int *p = a; for (i = 0; i < n; i++) {// printf("%d, ", p[i]);printf("%d, ", *(p + i));}printf("\n");return 0;
}
2、指针
https://blog.csdn.net/weixin_60546365/article/details/146464990
①指针大小与数据类型无关:无论指针指向什么类型的数据(int、char、double等),指针本身的大小只取决于系统的位数(32位或64位)。
指针大小与系统架构相关:
- 在32位系统上,指针大小为4字节。
- 在64位系统上,指针大小为8字节。
- 指针类型与数据类型的关系:虽然指针的大小与指向的数据类型无关,但在使用指针时,仍然需要确保指针类型与它所指向的数据类型匹配,以避免类型不匹配错误。
②指针加整数的含义
- a 是一个指针,假设它指向一个数组的首地址;i 是一个整数。
- a + i 表示将指针 a 向后移动 i 个单位。这里的“单位”是指指针所指向的数据类型大小。例如:
- 如果 a 是一个指向 int 类型的指针,那么 a + i 表示将指针 a 向后移动 i * sizeof(int) 字节。
- 如果 a 是一个指向 char 类型的指针,那么 a + i 表示将指针 a 向后移动 i * sizeof(char) 字节(sizeof(char) 通常为1字节)。
③野指针与空指针
- 野指针:赋任意数值,没有意义 → 此指针指向区域未知
- 空指针:赋值NULL,标志该指针没有任何指向
野指针不会直接引发错误,操作野指针指向的内存区域才会出问题
3、结构体
【嵌入式学习2】结构体-CSDN博客
①结构体使用:
- 如果是结构体变量,通过 . 操作
- 如果是结构体指针变量,通过 -> 操作
②结构体传参:
- 传值是指将参数的值拷贝一份传递给函数,函数内部对该参数的修改不会影响到原来的变量
- 传址是指将参数的地址传递给函数,函数内部可以通过该地址来访问原变量,并对其进行修改
4、函数
https://blog.csdn.net/weixin_60546365/article/details/146463482
回调函数:
- 函数指针变量做函数参数,函数指针变量指向的函数就是回调函数
- 回调函数可以增加函数的通用性,在不改变原函数的前提下,增加新功能
- 这里定义了一个名为
CallbackFunc
的函数指针类型,它指向的函数返回类型为void
,参数为一个int
和一个char
typedef void (*CallbackFunc)(int, char);
#include <stdio.h>// 定义函数,函数指针做形参
int calc(int a, int b, int (*p)(int, int)){// 通过函数指针变量调用函数,获取返回值int res = p(a, b);return res;
}// 定义加法函数
int add(int x, int y) {return x + y;
}// 定义减法函数
int sub(int x, int y) {return x - y;
}int main() {int result;// 回调加法函数result = calc(1, 2, add);printf("result = %d\n", result);// 回调减法函数result = calc(10, 5, sub);printf("result = %d\n", result);return 0;
}
回调函数的常见用途
-
事件处理
在图形用户界面编程中,回调函数常用于处理用户的输入事件(如点击按钮、键盘输入等)。
-
异步编程
在异步操作(如文件读写、网络通信)完成后,通过回调函数通知调用者操作已完成。
-
算法的扩展性
在一些算法中,可以使用回调函数来提供自定义的处理逻辑,增强算法的灵活性。
## 如何区分数组指针,指针数组,函数指针,结构体指针,指针偏移量
数组指针:指向整个数组的指针
- 数组指针指向的是整个数组的首地址,可以通过指针加偏移量访问数组中的元素
- 数组指针的解引用可以得到整个数组
//这里p是一个指向包含10个int元素的数组的指针。
int arr[10] = {0};
int (*p)[10] = &arr; // p指向数组arr
printf("%d\n", (*p)[5]); // 访问数组arr的第6个元素
指针数组:数组的每个元素是指针
- 指针数组本身是一个数组,其大小在声明时确定
- 每个元素是一个指针,可以指向不同的变量或内存地址
//这里p是一个包含10个int指针的数组。
int a = 1, b = 2, c = 3;
int *p[3] = {&a, &b, &c}; // 指针数组p的每个元素分别指向a、b、c
printf("%d\n", *p[1]); // 输出b的值
函数指针:指向函数的指针
- 函数指针可以指向函数,通过函数指针可以调用函数
- 函数指针的类型必须与它指向的函数的类型一致
//这里p是一个指向返回值为int,参数为两个int的函数的指针
int add(int x, int y) {return x + y;
}
int (*p)(int, int) = add; // p指向函数add
printf("%d\n", p(3, 4)); // 通过函数指针调用函数,输出7
结构体指针:指向结构体变量的指针
- 结构体指针可以通过指针访问结构体中的成员
- 结构体指针的解引用可以得到整个结构体
//这里p是一个指向struct Student类型的结构体变量的指针
struct Student {int id;char name[20];
};
struct Student s = {1, "Alice"};
struct Student *p = &s; // p指向结构体变量s
printf("%d %s\n", p->id, p->name); // 访问结构体成员
指针偏移量:通过指针加偏移量访问内存中的数据
- 指针偏移量通常用于访问数组中的元素或结构体中的成员
- 偏移量的计算基于指针的类型和步长
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr; // p指向数组arr的首地址
printf("%d\n", *(p + 2)); // 通过指针偏移量访问数组的第3个元素,输出3