高阶C语言|探索指针的根源之目(进阶指针)
文章目录
💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习!
👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对指针感兴趣的朋友!
在学习这篇文章之前,强烈建议先学习初阶指针哦~
传送门呈上~
初探C语言|一篇文章让你拿捏指针(初阶指针)
前言
C语言的指针被视为一项强大但复杂的工具,它允许程序直接操作内存,提高程序的灵活性和效率。虽然指针的基础用法很多人已经掌握,但更深入的理解能够帮助开发者解决更复杂的编程问题。本文将详细探讨C语言中一些进阶的指针概念,包括字符指针、数组指针、指针数组、函数指针、指向函数指针数组的指针等,并通过示例深入讲解它们的用法和应用场景。
1. 字符指针(char*
)
字符指针是指向单个字符或字符串的指针,它在处理字符串和字符数组时特别有用。在C语言中,字符串是一个字符数组,字符指针通常用于访问字符串的首地址。
1.1 字符串常量与指针
在C语言中,字符串本质上是字符的数组,并且以\0
结尾,表示字符串的结束。字符指针指向的是数组的首元素。例如:
const char* pstr = "Hello, World!";
pstr
是一个字符指针,指向常量字符串的首字符。需要注意的是,pstr
存储的是字符串的内存地址,而不是字符串本身。
1.2 字符指针的使用
通过字符指针,我们可以访问字符串中的每个字符:
#include <stdio.h>
int main() {
const char* pstr = "Hello, World!";
while (*pstr != '\0') {
printf("%c ", *pstr);
pstr++; // 指针自增,访问下一个字符
}
return 0;
}
输出:
H e l l o , W o r l d !
2. 数组指针与指针数组
在C语言中,数组与指针之间有紧密的关系。我们经常需要使用指针来处理数组。理解数组指针和指针数组的区别对于编写高效的代码至关重要。
2.1 指针数组
指针数组是一个数组,其中每个元素都是指向某种数据类型的指针。通常,用指针数组来存储多个指向不同数据的指针。
int* arr[10]; // 定义了一个包含10个指针的数组
每个元素都是一个指向整数的指针,可以通过数组索引访问指针:
#include <stdio.h>
int main() {
int a = 10, b = 20, c = 30;
int* arr[3] = {&a, &b, &c};
for (int i = 0; i < 3; i++) {
printf("Value at arr[%d]: %d\n", i, *arr[i]);
}
return 0;
}
输出:
Value at arr[0]: 10
Value at arr[1]: 20
Value at arr[2]: 30
2.2 数组指针
数组指针是一个指向整个数组的指针。它与指针数组的关键区别在于,数组指针指向的是整个数组,而指针数组指向的是数组中的各个元素。
例如,二维数组可以通过数组指针传递给函数:
int (*arr)[10]; // 指向包含10个整数的数组的指针
#include <stdio.h>
void print_array(int (*arr)[3]) {
for (int i = 0; i < 3; i++) {
printf("%d ", (*arr)[i]);
}
printf("\n");
}
int main() {
int arr[3] = {1, 2, 3};
print_array(&arr);
return 0;
}
3. 数组与指针传参
在C语言中,当我们将数组作为参数传递给函数时,传递的实际上是数组的首地址。通过指针访问数组,可以方便地进行数组的操作。
3.1 一维数组传参
void print_array(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
由于数组本质上是指针类型,arr[]
等价于int* arr
。这样,数组的所有元素都可以通过指针进行访问。
3.2 二维数组传参
二维数组在传递时,需要指定第二维的大小,这样才能正确计算内存偏移量。例如:
void print_2d_array(int arr[3][4]) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
4. 函数指针(function pointer
)
函数指针是指向函数的指针,能够存储一个函数的地址。通过函数指针,我们可以实现动态调用函数,这对于回调函数和事件驱动的编程非常有用。
4.1 函数指针的基本用法
定义一个函数指针并通过它调用函数:
#include <stdio.h>
void test(int a) {
printf("Test: %d\n", a);
}
int main() {
void (*func_ptr)(int) = test;
func_ptr(10); // 通过函数指针调用 test 函数
return 0;
}
4.2 使用函数指针数组
函数指针数组是一个数组,其中每个元素都是一个指向函数的指针。常用于实现多态性或函数的动态调度。
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
int div(int a, int b) { return a / b; }
int main() {
int (*ops[4])(int, int) = {add, sub, mul, div};
int x = 10, y = 5;
printf("Addition: %d\n", ops[0](x, y));
printf("Subtraction: %d\n", ops[1](x, y));
printf("Multiplication: %d\n", ops[2](x, y));
printf("Division: %d\n", ops[3](x, y));
return 0;
}
输出:
Addition: 15
Subtraction: 5
Multiplication: 50
Division: 2
5. 指向函数指针数组的指针
指向函数指针数组的指针是一种较为复杂的结构,允许通过指针访问一个存储函数指针的数组。它在复杂的回调机制或动态函数调用中非常有用。
int (*(*pf)[10])(int, int);
这种复杂的结构通常用于处理多个回调函数或多态调用。
6. 回调函数(Callback Function)
回调函数是通过函数指针传递的函数,它通常在某个事件发生时被调用。在C语言中,回调函数广泛用于处理异步事件或某些特定条件的处理。
例如,标准库中的qsort
函数就是一个典型的回调函数应用场景:
#include <stdio.h>
#include <stdlib.h>
int compare(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
int main() {
int arr[] = {5, 3, 8, 1, 2};
qsort(arr, 5, sizeof(int), compare);
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
return 0;
}
在这个例子中,compare
函数作为回调函数传递给qsort
,用于比较数组元素,从而完成排序。
完~
原文地址:https://blog.csdn.net/Surplus886/article/details/145118733
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!