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;        保持指针类型与指向的内存类型一致

posted @ 2025-12-18 20:42  clnchanpin  阅读(76)  评论(0)    收藏  举报