C语言中指针有哪些?如何正确运用指针
在C语言中,指针的类型丰富且功能强大,正确使用指针是掌握C语言的关键所在,以下是指针的分类以及如何正确使用指针的详细说明:
一、指针的分类
1、普通指针——指向基本数据类型
指向int、char、float等基本类型的指针
int *p_int;
char *p_char;
float *p_float;
2、void指针——无类型指针
可指向任意类型的指针,需显式转换为具体类型才能操作,常用于通用函数。
void *p_void;
int a = 10;
p_void = &a;
int *p = (int*)p_void;
printf("%d", *p);
// 输出10
3、函数指针——指向函数的指针变量
存储函数的入口地址,可通过指针调用函数,用于回调、函数表等。
int add(int a, int b) { return a + b; }
int (*p_func)(int, int) = add;
printf("%d", p_func(2, 3));
// 输出5
4、指针函数——返回“指针类型”的函数
指针函数是返回 “指针类型” 的函数,即函数的返回值是一个指针。注:*直接跟在函数名前,无需额外括号
// 函数:返回字符串的拷贝(指针函数,返回char*指针)
char *str_dup(const char *src) {
int len = strlen(src) + 1;
char *dst = (char*)malloc(len);
strcpy(dst, src);
return dst; // 返回动态分配的内存指针
}
int main() {
char *s = str_dup("Hello");
printf("%s\n", s); // 输出Hello
free(s); // 释放动态内存
return 0;
}
5、指针数组——数组元素为指针
数组的每个元素都是一个指针,常用于存储多个地址,字符串数组等等。
char *str_arr[3] = {"Hello", "World", "C"};
printf("%s", str_arr[0]);
// 输出Hello
6、数组指针——指向数组的指针
指向整个数组的指针,用于操作二维数组或数组的整体特性。
int arr[3] = {1, 2, 3};
int (*p_arr)[3] = &arr;
printf("%d", (*p_arr)[0]);
// 输出1
7、多级指针——指针的指针
指向“指针变量”的指针,一级指针 *p、二级指针 **p、三级指针 ***p,用于修改指针本身的指向。
int a = 10;
int *p = &a;
int **pp = &p;
printf("%d", **pp);
// 输出10
二、如何正确使用指针
1、强制初始化,避免野指针
(1)野指针:
a.定义
未被正确初始化、或指向的内存已释放却仍被访问的指针,本质是指针指向了不可控的内存区域。
b.野指针的危害
程序崩溃(段错误)、数据篡改,破坏其他变量或程序逻辑。
c.避免方法
· 指针定义时强制初始化,如int *p=NULL;
int *p = NULL;
int a = 20;
p = &a;
· free后立即将指针置空,如free(p); p=NULL;
int *p = (int*)malloc(sizeof(int));
if (p == NULL) {
printf("内存分配失败\n");
return -1;
}
*p = 100;
free(p);
p = NULL;
· 指针运算时严格控制边界,避免越界
int arr[5] = {1,2,3,4,5};
int *p = arr;
for (int i = 0; i < 5; i++) {
printf("%d ", *p++);
}
// 错误示例:越界访问
// p = &arr[5]; // arr[5]超出数组范围,*p操作非法
· 避免隐式类型转换,指针类型需与指向的变量/数组类型一致,若是void指针转换为具体类型时需要显式强转
char c = 'A';
int *p = (int*)&c; // 不推荐(类型不匹配,可能导致内存访问错误)
// 正确:使用同类型指针
char *p_char = &c;
· 函数传指针时区分修改值与修改指针指向,若需在函数内修改变量的值,传指针即可;若需修改指针的指向,需传二级指针
// 示例1:修改变量的值(传一级指针)
void modify_val(int *p) {
*p = 100; // 修改p指向的变量的值
}
// 示例2:修改指针的指向(传二级指针)
void modify_ptr(int **pp) {
int a = 200;
*pp = &a; // 修改pp指向的指针(p)的指向
}
int main() {
int a = 10;
int *p = &a;
modify_val(p); // a变为100
modify_ptr(&p); // p指向a(200)
return 0;
}
2、常见错误与避坑总结
(1)野指针
int *p; *p=10; 解决方法:初始化指针为NULL或具体地址
(2)内存泄漏
malloc后没有free 解决方法:确保malloc与free配对使用
(3)指针越界
int arr[3];arr[5]=10; 解决方法:严格控制数组下标范围
(4)类型不匹配
char *p=(char *)malloc(4);int *q=p; 保持指针类型与指向的内存类型一致
浙公网安备 33010602011771号