C语言入门(8)--指针及部分案例

C语言指针

指针是C语言中非常核心和强大的功能,它为程序提供了极高的灵活性和效率。下面我们来聊聊C语言中的指针。

这篇内容稍微较长,因为加入了部分案例,希望对耐心的你有帮助。

案例最好自己手打一遍,印象会更深刻。

1. 指针的概念

在C语言中,指针是一个变量,其存储的值是另一个变量的内存地址。指针变量的使用允许程序直接访问和操作内存地址,这是C语言区别于其他高级语言的重要特性。

2. 指针的声明和初始化

声明一个指针需要指定指针的类型,这决定了指针可以指向的数据类型。指针声明的一般形式为:

type *var_name;

其中type是指针的基类型,var_name是指针变量的名称。例如,声明一个指向整数的指针:

int *ip;

初始化指针通常涉及到取一个变量的地址:

int var = 20;
ip = &var;

这里&是取地址运算符,用于获取var的内存地址,并将其赋值给指针ip

3. 指针的解引用

通过指针访问其指向的变量的值称为解引用。解引用使用*操作符:

printf("%d", *ip); // 输出ip指向的变量的值

这行代码会输出var的值,因为ip指向var的地址。

4. 指针和数组的关系

数组名在大多数情况下可以作为指向数组首元素的指针使用。例如:

int arr[5] = {
    
    1, 2, 3, 4, 5};
int *p = arr; // p现在指向数组arr的首元素

通过指针访问数组元素:

printf("%d", *(p + 2)); // 输出数组的第三个元素
5. 指针的算术运算

指针可以进行加法和减法运算,这通常用于数组遍历:

for (int i = 0; i < 5; i++) {
    
    
    printf("%d ", *(p + i));
}

这段代码会遍历数组arr并打印每个元素的值。

6. 指针的类型

指针的类型决定了指针解引用时可以访问的内存大小。例如,int*类型的指针解引用可以访问4个字节(假设在32位系统上),而char*类型的指针解引用只能访问1个字节。

7. 指针数组和数组指针
  • 指针数组:一个数组,其元素都是指针。
  • 数组指针:一个指针,它指向一个数组。
8. 函数指针

函数指针是指向函数的指针。它可以存储函数的地址,并可以被用来调用函数:

int (*funcPtr)(int, int) = add; // funcPtr是指向返回int类型且接受两个int参数的函数的指针
int result = funcPtr(5, 3); // 调用add函数
9. 野指针

野指针是未初始化的指针,它指向一个不确定的内存地址。使用野指针可能导致程序崩溃或数据损坏。

10. 指针和const
  • 常量指针:指针指向的值不可变。
  • 指针常量:指针本身的值不可变,即指向的地址不可变。

接下来进行咱们的案例部分。

C语言指针案例

在C语言中,指针是一种特殊的变量,它存储的是另一个变量的内存地址。下面是一些指针的使用实例,以及相关的基础内容。

实例1:指针的基本使用
#include <stdio.h>

int main() {
    
    
    int var = 10;
    int *ptr = &var; // ptr 指向 var 的地址

    printf("var 的值: %d\n", var);
    printf("var 的地址: %p\n", (void*)&var);
    printf("ptr 存储的地址: %p\n", (void*)ptr);
    printf("*ptr 的值: %d\n", *ptr); // 输出 ptr 指向地址的值

    return 0;
}

这个程序演示了如何声明一个指针,如何让指针指向一个变量的地址,以及如何通过指针来访问变量的值。

实例2:指针作为函数参数
#include <stdio.h>

void increment(int *p) {
    
    
    *p = *p + 1; // 将 p 指向的值增加 1
}

int main() {
    
    
    int x = 10;
    increment(&x); // 传递 x 的地址给函数
    printf("Incremented value: %d\n", x); // 输出增加后的值

    return 0;
}

这个实例展示了如何通过指针作为函数参数来修改实际参数的值。

实例3:指针与数组
#include <stdio.h>

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

    for (int i = 0; i < 5; i++) {
    
    
        printf("arr[%d] = %d\n", i, *(p + i)); // 通过指针访问数组元素
    }

    return 0;
}

这个程序演示了指针与数组的关系,以及如何使用指针来遍历数组。

实例4:指针数组和数组指针
#include <stdio.h>

int main() {
    
    
    int a = 10, b = 20, c = 30;
    int *arr[] = {
    
    &a, &b, &c}; // 指针数组,存储指针
    int (*ptr)[3] = &arr; // 数组指针,指向包含3个int指针的数组

    printf("%d\n", *(*ptr + 0)); // 输出10
    printf("%d\n", *(*ptr + 1)); // 输出20
    printf("%d\n", *(*ptr + 2)); // 输出30

    return 0;
}

这个实例展示了指针数组和数组指针的概念,以及如何使用它们。

实例5:函数指针和回调函数
#include <stdio.h>

// 函数声明
int max(int, int);

// 函数指针变量
int (*funcPtr)(int, int) = max;

int max(int a, int b) {
    
    
    return a > b ? a : b;
}

int main() {
    
    
    int x = 50, y = 70, z;
    z = (*funcPtr)(x, y); // 通过函数指针调用函数
    printf("The maximum of %d and %d is %d\n", x, y, z);

    return 0;
}

这个程序演示了函数指针的使用,以及如何通过函数指针调用函数。

指针的算术运算

指针的算术运算包括加法、减法、自增和自减。这些操作通常用于数组遍历。

#include <stdio.h>

int main() {
    
    
    int arr[] = {
    
    10, 20, 30, 40, 50};
    int *p = arr; // p 指向数组的第一个元素

    printf("%d\n", *(p + 1)); // 访问第二个元素,输出20
    p++; // p 移动到下一个元素
    printf("%d\n", *p); // 输出30

    return 0;
}

这个程序演示了指针的加法和自增操作。

空指针和NULL

在C语言中,NULL是一个宏定义,代表空指针。空指针是一个不指向任何有效对象的指针。

#include <stdio.h>

int main() {
    
    
    int *ptr = NULL; // 初始化指针为NULL

    if (ptr == NULL) {
    
    
        printf("ptr is null\n");
    }

    return 0;
}

这个程序演示了如何检查空指针。

通过这些实例和基础内容,你应该对C语言中的指针有了更深入的理解。

指针是C语言中非常强大和灵活的特性。

但同时也需要谨慎使用,以避免出现内存泄漏、野指针等错误。

这篇文章稍微较长,读到这里,感谢你的耐心。

关于C语言指针和案例的内容,咱们到这告一段落。

希望能对你有帮助。

下期见!

猜你喜欢

转载自blog.csdn.net/Chen7Chan/article/details/143314538