C语言中指针详解

216 阅读3分钟

指针是C语言中一个极其重要的概念,它让程序员能够直接操作内存,提高程序的效率和可扩展性。本文将精简地认识C语言中指针的基础概念,并为进阶认识打下基础。

1. 指针的概念

指针本质上是一个地址值(memory address)。它指向一块内存,该块内存中存放了一个值。从实际上看,指针是一个用来存放内存地址的变量。

2. 指针的声明

在C语言中,可以通过以下方式声明指针:

类型 *指针变量名;

例如:

int *p;  // 声明一个指向int类型的指针
char *q; // 声明一个指向char类型的指针

3. 指针的基础操作

3.1 取地址操作符“&”

“&”用于取一个变量的内存地址:

int a = 10;
int *p = &a;  // p将存放变量a的地址

3.2 指针解指操作符“*”

“*”用于通过指针取存放在指针所指向内存地址中的值:

int a = 10;
int *p = &a;
printf("%d\n", *p);  // 输出10

3.3 修改指针所指向内存的值

通过“*”可以修改指针指向的内存中的值:

int a = 10;
int *p = &a;
*p = 20;  // 修改a的值
printf("%d\n", a);  // 输出20

4. 指针和数组

在C语言中,数组同样可以和指针配合使用:

int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;  // 指针指向数组的第一个元素

for (int i = 0; i < 5; i++) {
    printf("%d ", *(p + i));  // 通过指针查看数组元素
}

5. 指针和函数

指针可以指向一个函数,这种指针称为函数指针:

5.1 函数指针的声明

类型 (*函数指针名)(参数列表);

例如:

int add(int a, int b) {
    return a + b;
}

int (*p)(int, int) = add;  // 声明一个函数指针
printf("%d\n", p(3, 4));  // 通过函数指针调用函数

5.2 函数指针的应用

函数指针应用于多样化函数调用,如实现回调机制:

void callback(int (*func)(int, int), int x, int y) {
    printf("Result: %d\n", func(x, y));
}

int multiply(int a, int b) {
    return a * b;
}

int main() {
    callback(add, 3, 5);      // 传递add函数
    callback(multiply, 3, 5); // 传递multiply函数
    return 0;
}

6. 指针的高级应用

6.1 指针指向指针

指针可以指向另一个指针,称为指针指针:

int a = 10;
int *p = &a;
int **pp = &p;  // pp指向p

printf("%d\n", **pp);  // 通过pp读取a的值

6.2 动态内存分配

C语言提供了malloc和calloc等函数,用于动态分配内存:

int *p = (int *)malloc(sizeof(int) * 5);  // 分配一个能存放5个int值的内存

if (p != NULL) {
    for (int i = 0; i < 5; i++) {
        p[i] = i * 10;
    }

    for (int i = 0; i < 5; i++) {
        printf("%d ", p[i]);
    }
    free(p);  // 释放内存
}

7. 常见的指针错误

7.1 释放里存指针后再次访问

已释放内存的指针如果再次访问,将会导致不可预料的错误:

int *p = (int *)malloc(sizeof(int));
*p = 100;
free(p);
printf("%d\n", *p);  // 错误!

7.2 重复释放内存

指针指向的内存不能重复释放:

int *p = (int *)malloc(sizeof(int));
free(p);
free(p);  // 错误!

7.3 指针跳出合法范围

通过指针操作的范围必须是合法的,否则将导致错误:

int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;

for (int i = 0; i <= 5; i++) {
    printf("%d ", *(p + i));  // 最后一步跳出合法范围
}

8. 结论

指针是C语言中极其强大的工具,它提供了直接操作内存的能力,但同时也增加了程序的处理复杂性和错误的可能性。通过熟练控制指针,稍微小心,能夠最大化地发挥它的优势,为程序的高效性和可扩展性拆胜。