C语言指针详解:从基础概念到文件与函数指针实战
C语言中,指针是连接程序与内存的桥梁。本文系统梳理指针的基础定义、数组与字符串的地址访问、二级指针的逻辑关系、函数指针的回调应用,以及通过FILE结构体进行的文件读写操作,帮助开发者建立完整的指针知识体系。
一、 何为指针与内存访问
指针的本质是一个变量,其存储的内容是另一个变量的内存地址。通过指针,程序不仅可以读取变量的值,还能直接修改该地址处的数据。在32位系统中,指针通常占用4字节;在64位系统中,占用8字节。
以下代码演示了如何声明整型指针并获取变量地址:
#include <stdio.h>
#include <stdlib.h>
int main() {
int a = 5;
int *p;
p = &a;
printf("a的值: %d\n", a);
printf("p指向的地址: %p\n", p);
printf("p指向的值(*p): %d\n", *p); // 解引用
// 释放内存(若动态分配)
// free(p);
return 0;
}
输出结果将显示变量 a 的具体地址数值,而 *p 则直接关联到 a 的值。修改 *p 等同于修改 a。
二、 数组指针与指针数组的区别
第1步:理解数组名即首地址
在C语言中,一维数组名代表数组首元素的地址。例如 int arr[5] 中,arr 等价于 &arr[0]。因此,可以使用指针遍历数组:
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr; // 指针指向数组首元素
for (int i = 0; i < 5; i++) {
printf("&arr[%d]=%p, arr[%d]=%d\n", i, p, i, *(p+i));
}
return 0;
}
第2步:区分“数组指针”与“指针数组”
这两个概念极易混淆,关键在于优先级:
- 指针数组 (Array of Pointers):
int *p[5]。这是一个包含5个整型指针的数组。[]优先级高于*,所以先结合成数组,每个元素都是指针。 - 数组指针 (Pointer to Array):
int (*p)[5]。这是一个指向包含5个整数的一维数组的指针。括号改变优先级,先结合指针,再结合数组。
在上面的例子中,如果使用指针数组,则是为每个元素单独分配地址存储:
int arr[5] = {1, 2, 3, 4, 5};
int *ptr_arr[5];
for(int i=0; i<5; i++) ptr_arr[i] = &arr[i];
三、 字符串与字符数组的指针操作
C语言没有内置的字符串类型,而是使用以 '\0' 结尾的字符数组。一个长度为 N 的字符串,实际需要的数组大小为 N+1。
直接初始化字符串常量时,编译器会在末尾自动添加 '\0':
#include <stdio.h>
int main() {
char str[] = "hello"; // 实际上是6个字节{'h','e','l','l','o','\0'}
printf("字符串: %s\n", str);
// 使用字符指针访问
char *p = "hello";
printf("第2个字符: %c\n", p[1]); // 输出 'e'
return 0;
}
四、 多维指针与二级指针
指针可以指向指针,形成多级间接寻址,这在处理二维数组或动态调整参数时非常有用。二级指针 **p 保存了一级指针的地址。
#include <stdio.h>
int main() {
int a = 10;
int *p = &a; // 一级指针,存a的地址
int **pp = &p; // 二级指针,存p的地址
printf("a=%d, *p=%d, **pp=%d\n", a, *p, **pp);
return 0;
}
五、 函数指针与回调机制
函数在内存中也占据地址。函数指针允许我们将函数作为参数传递给其他函数,从而实现回调机制,这在实现排序算法(如 qsort)或事件驱动模型时非常关键。
第1步:声明函数指针
格式:返回值类型 (*指针名) (参数列表)。
int add(int x, int y); // 原型
int (*func_ptr)(int, int); // 声明函数指针
第2步:使用函数指针调用函数
#include <stdio.h>
void process(int val, int (*op)(int)) {
printf("Result: %d\n", op(val));
}
int double_val(int v) { return v * 2; }
int main() {
process(5, double_val); // 传递函数地址
return 0;
}
六、 指针函数与文件操作
指针函数
返回值为指针的函数。最常见的是返回字符串地址:
char* get_str() {
static char str[] = "Hello";
return str;
}
文件指针 (FILE*)
C语言通过标准库 stdio.h 中的 FILE 结构体管理文件。操作顺序如下:
- 打开:使用
fopen(),返回文件指针。 - 读写:使用
fscanf,fprintf,fgets等。 - 关闭:使用
fclose()释放资源。
#include <stdio.h>
int main() {
FILE *fp;
char buffer[100];
// 写文件
fp = fopen("test.txt", "w");
if (fp != NULL) {
fprintf(fp, "Hello File!\n");
fclose(fp);
}
// 读文件
fp = fopen("test.txt", "r");
if (fp != NULL) {
fgets(buffer, sizeof(buffer), fp); // 安全读取一行
printf("Content: %s", buffer);
fclose(fp);
}
return 0;
}
以上就是C语言指针的详细内容,更多关于C语言进阶的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













