FreeRTOS-C语言指针笔记
文章目录
- 一级指针
- 指针基本概念
- 指针使用示例
- 代码说明
- 二、二级指针
- 二级指针重点解析
一级指针
C语言中的指针是一个非常重要的概念,它存储了变量的内存地址。指针的使用可以使程序更加高效,尤其在处理数组、字符串和动态内存分配时。
指针基本概念
- 指针变量:用于存储内存地址的变量
- 取地址符
&
:获取变量的内存地址 - 解引用符
*
:访问指针所指向地址的内容
指针使用示例
下面是一些常见的指针使用示例:
可以运行
#include <stdio.h>// 1. 基本指针操作
void basicPointerExample() {int num = 10;int *p; // 声明一个int类型的指针p = # // 将num的地址赋值给指针pprintf("num的值: %d\n", num);printf("num的地址: %p\n", &num);printf("指针p存储的地址: %p\n", p);printf("指针p指向的值: %d\n", *p);*p = 20; // 通过指针修改num的值printf("修改后num的值: %d\n", num);
}// 2. 指针作为函数参数(实现值的交换)
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}// 3. 指针与数组
void pointerAndArray() {int arr[] = {1, 2, 3, 4, 5};int *p = arr; // 数组名本身就是第一个元素的地址printf("\n数组元素: ");for(int i = 0; i < 5; i++) {// 以下两种方式等价printf("%d ", *(p + i));// printf("%d ", arr[i]);}printf("\n");
}// 4. 指针与字符串
void pointerAndString() {char *str = "Hello, World!"; // 字符串指针printf("\n字符串内容: ");// 使用指针遍历字符串while(*str != '\0') {printf("%c", *str);str++; // 指针自增,指向 next 字符}printf("\n");
}// 5. 指针数组
void pointerArray() {char *names[] = {"Alice", "Bob", "Charlie", "David"};printf("\n指针数组中的字符串: ");for(int i = 0; i < 4; i++) {printf("%s ", names[i]);}printf("\n");
}int main() {basicPointerExample();int x = 100, y = 200;printf("\n交换前: x = %d, y = %d\n", x, y);swap(&x, &y);printf("交换后: x = %d, y = %d\n", x, y);pointerAndArray();pointerAndString();pointerArray();return 0;
}
代码说明
- 基本指针操作:展示了如何声明指针、获取变量地址、通过指针访问和修改变量值
- 指针作为函数参数:通过指针在函数内部修改外部变量的值,实现了两个数的交换
- 指针与数组:数组名本质上是指向第一个元素的指针,演示了如何通过指针访问数组元素
- 指针与字符串:字符串可以用指针表示,演示了如何通过指针遍历字符串
- 指针数组:数组中的每个元素都是指针,这里用指针数组存储多个字符串
指针的使用需要特别注意避免空指针、野指针等问题,这些可能会导致程序崩溃或不可预期的行为。正确使用指针可以使C程序更加灵活和高效。
二、二级指针
在C语言中,二级指针是指向指针的指针,它存储的是另一个指针变量的地址。二级指针在处理指针数组、动态二维数组以及需要修改指针本身的场景中非常有用。
下面在原有代码基础上添加二级指针的使用示例:
#include <stdio.h>
#include <stdlib.h> // 用于动态内存分配// 1. 基本指针操作
void basicPointerExample() {int num = 10;int *p; // 声明一个int类型的指针p = # // 将num的地址赋值给指针pprintf("num的值: %d\n", num);printf("num的地址: %p\n", &num);printf("指针p存储的地址: %p\n", p);printf("指针p指向的值: %d\n", *p);*p = 20; // 通过指针修改num的值printf("修改后num的值: %d\n", num);
}// 2. 指针作为函数参数(实现值的交换)
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}// 3. 指针与数组
void pointerAndArray() {int arr[] = {1, 2, 3, 4, 5};int *p = arr; // 数组名本身就是第一个元素的地址printf("\n数组元素: ");for(int i = 0; i < 5; i++) {// 以下两种方式等价printf("%d ", *(p + i));// printf("%d ", arr[i]);}printf("\n");
}// 4. 指针与字符串
void pointerAndString() {char *str = "Hello, World!"; // 字符串指针printf("\n字符串内容: ");// 使用指针遍历字符串while(*str != '\0') {printf("%c", *str);str++; // 指针自增,指向 next 字符}printf("\n");
}// 5. 指针数组
void pointerArray() {char *names[] = {"Alice", "Bob", "Charlie", "David"};printf("\n指针数组中的字符串: ");for(int i = 0; i < 4; i++) {printf("%s ", names[i]);}printf("\n");
}// 6. 二级指针使用示例
void doublePointerExample() {int num = 100;int *p = # // 一级指针,指向numint **pp = &p; // 二级指针,指向指针pprintf("\n=== 二级指针基本操作 ===\n");printf("num的值: %d\n", num);printf("p指向的值: %d\n", *p);printf("pp指向的指针所指向的值: %d\n", **pp);printf("num的地址: %p\n", &num);printf("p存储的地址: %p\n", p);printf("pp存储的地址: %p\n", pp);printf("p本身的地址: %p\n", &p);
}// 7. 二级指针与指针数组
void doublePointerAndPointerArray() {char *languages[] = {"C", "Python", "Java", "JavaScript"};char **pp; // 二级指针,用于指向指针数组元素printf("\n=== 二级指针访问指针数组 ===\n");// 二级指针遍历指针数组pp = languages; // 指向数组首元素for(int i = 0; i < 4; i++) {printf("语言: %s, 地址: %p\n", *pp, pp);pp++; // 移动到下一个指针元素}
}// 8. 二级指针作为函数参数(修改指针本身)
void allocateMemory(int **ptr, int size) {// 为指针分配内存,需要二级指针才能修改外部指针*ptr = (int*)malloc(size * sizeof(int));if(*ptr == NULL) {printf("\n内存分配失败!\n");return;}// 初始化分配的内存for(int i = 0; i < size; i++) {*(*ptr + i) = i * 10;}
}int main() {basicPointerExample();int x = 100, y = 200;printf("\n交换前: x = %d, y = %d\n", x, y);swap(&x, &y);printf("交换后: x = %d, y = %d\n", x, y);pointerAndArray();pointerAndString();pointerArray();// 演示二级指针doublePointerExample();doublePointerAndPointerArray();// 二级指针作为函数参数示例int *arr = NULL;allocateMemory(&arr, 5); // 传递指针的地址if(arr != NULL) {printf("\n通过二级指针分配的数组: ");for(int i = 0; i < 5; i++) {printf("%d ", arr[i]);}printf("\n");free(arr); // 释放内存}return 0;
}
二级指针重点解析
-
二级指针的定义与初始化:
int num = 100; int *p = # // 一级指针 int **pp = &p; // 二级指针,指向指针p
这里
pp
就是二级指针,它存储的是一级指针p
的地址。 -
二级指针的解引用:
*pp
:得到一级指针p
的值(即num
的地址)**pp
:通过两次解引用,得到最终变量num
的值
-
二级指针的主要用途:
- 访问指针数组:如示例中遍历存储字符串的指针数组
- 作为函数参数修改指针本身:当需要在函数内部为指针分配内存或修改指针指向时
- 处理动态二维数组:二级指针常用来表示动态分配的二维数组
-
使用注意事项:
- 二级指针也可能出现空指针问题,使用前需检查
- 多级指针会增加代码复杂度,应避免过度使用
- 动态分配内存后需记得释放,防止内存泄漏
通过二级指针,我们可以更灵活地操作指针本身,这在处理复杂数据结构和动态内存分配时特别有用。