指针是C语言中一个强大的工具,它允许我们直接操作内存地址。指针的基本概念是指向内存中一个特定位置的变量。
int *ptr;
int var = 10;
ptr = &var; // ptr现在指向var的地址
2. 指针与数组数组名在C语言中是一个指向数组首元素的指针。通过指针运算,我们可以轻松遍历数组。
int arr[] = {10, 20, 30};
int *p = arr; // p指向arr的第一个元素
for (int i = 0; i < 3; i++) {
printf("%d ", *(p + i)); // 输出数组元素
}
3. 指针的指针一个指向指针的指针,通常用于创建动态数据结构,如链表。
int **pptr;
int *ptr = malloc(sizeof(int));
*ptr = 5;
pptr = &ptr; // pptr指向ptr的地址
4. 函数指针函数指针允许我们将函数作为参数传递给其他函数,或者从函数返回函数。
void func() {
printf("Hello, World!\n");
}
void (*funcPtr)() = func; // 创建指向func的函数指针
funcPtr(); // 调用func函数
5. 指针与内存分配malloc 和 free 是动态内存分配的核心,它们允许我们在运行时分配和释放内存。
int *dynamicArray = malloc(10 * sizeof(int));
if (dynamicArray == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
// 使用动态分配的内存
free(dynamicArray); // 释放内存
6. 指针数组与指针的数组指针数组是存储指针的数组,而指针的数组是一个数组,其元素是指针。
int *arr[5]; // 指针数组,存储5个int指针
int var1 = 10, var2 = 20;
arr[0] = &var1;
arr[1] = &var2;
7. 指针与结构体结构体可以包含指针,这使得我们可以创建复杂的数据结构。
typedef struct {
int *data;
int size;
} DynamicArray;
DynamicArray *createArray(int size) {
DynamicArray *array = malloc(sizeof(DynamicArray));
array->data = malloc(size * sizeof(int));
array->size = size;
return array;
}
8. 指针的安全性指针操作不当会导致内存泄漏、野指针和程序崩溃等问题。
void safeFree(void **ptr) {
if (*ptr != NULL) {
free(*ptr);
*ptr = NULL;
}
}
9. 指针运算与数组指针运算是数组遍历的基础,但需要小心越界问题。
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;
for (int i = 0; i < 5; i++) {
printf("%d ", *(p + i));
}
// 注意:p + 5 是越界的
10. 指针与字符串字符串在C语言中以字符数组的形式存在,其末尾以空字符 \0 结束。
char str[] = "Hello";
char *p = str;
while (*p) {
printf("%c", *p);
p++;
}
11. 指针的高级技巧使用 const 限定指针,防止修改指针指向的值。
使用 void* 指针进行类型无关的内存操作。
利用指针实现回调函数。
const int *constIntPtr = &var; // 指向const int的const指针
void *voidPtr = malloc(10); // 可以指向任何类型的数据
typedef void (*Callback)(int); // 回调函数类型定义
12. 结语指针是C语言中的核心概念,掌握指针的使用可以极大地提升编程能力。但同时,指针也是一把双刃剑,需要谨慎使用以避免潜在的错误。通过不断实践和学习,你将能够熟练地运用指针,编写出高效且安全的C语言程序。