当前位置: 首页 > article >正文

C语言指针专题五 -- void和const指针

目录

一、void指针(通用指针)

1. 核心原理

2. 代码示例

二、const指针(常量指针)

1. 核心原理

2. 代码示例

三、void指针与const指针的结合使用

四、关键总结


 

一、void指针(通用指针)

1. 核心原理
  • 无类型指针void*是一种通用指针类型,可以指向任意类型的数据,但 不能直接解引用(需强制类型转换)。

  • 用途

    • 实现泛型编程(如qsortmemcpy等标准库函数)。

    • 动态内存分配时返回未指定类型的指针。

  • 特点

    • 赋值给其他类型指针时需显式类型转换。

    • 不接受指针算术运算(如void* p++;是非法的,因为步长未知)。

2. 代码示例

示例1:泛型交换函数

#include <stdio.h>
#include <string.h>

// 使用void*实现通用数据交换
void swap(void *a, void *b, size_t size) {
    char temp[size]; // 使用字符数组暂存数据(按字节操作)
    memcpy(temp, a, size);
    memcpy(a, b, size);
    memcpy(b, temp, size);
}

int main() {
    int x = 10, y = 20;
    printf("Before swap: x=%d, y=%d\n", x, y);
    swap(&x, &y, sizeof(int));
    printf("After swap: x=%d, y=%d\n", x, y); // 输出x=20, y=10

    double a = 3.14, b = 6.28;
    printf("Before swap: a=%.2f, b=%.2f\n", a, b);
    swap(&a, &b, sizeof(double));
    printf("After swap: a=%.2f, b=%.2f\n", a, b); // 输出a=6.28, b=3.14
    return 0;
}

示例2:动态内存分配与类型转换

#include <stdio.h>
#include <stdlib.h>

int main() {
    void *ptr = malloc(sizeof(int)); // 分配int类型内存
    if (ptr == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }

    // 转换为int*后赋值
    int *int_ptr = (int*)ptr;
    *int_ptr = 42;
    printf("值: %d\n", *int_ptr); // 输出42

    free(ptr); // 释放内存
    return 0;
}

二、const指针(常量指针)

1. 核心原理
  • 保护数据不被修改const关键字用于限制指针的访问权限,根据const的位置不同,分为三种情况:

    1. 指向常量的指针const int* p):

      • 指针可以指向其他地址,但 不能通过指针修改数据

    2. 指针本身为常量int* const p):

      • 指针的指向不可变,但 可以修改指向的数据

    3. 指向常量的常量指针const int* const p):

      • 指针的指向和指向的数据均不可变。

2. 代码示例

示例1:指向常量的指针

#include <stdio.h>

int main() {
    int a = 10;
    const int *p = &a; // p指向的数据不可修改

    printf("初始值: %d\n", *p); // 输出10
    // *p = 20; // 错误!无法通过p修改a的值

    int b = 30;
    p = &b; // 合法:p可以指向其他地址
    printf("新值: %d\n", *p); // 输出30
    return 0;
}

示例2:常量指针

#include <stdio.h>

int main() {
    int a = 10;
    int *const p = &a; // p的指向不可变

    *p = 20; // 合法:可以修改指向的数据
    printf("a的值: %d\n", a); // 输出20

    int b = 30;
    // p = &b; // 错误!p的指向不可修改
    return 0;
}

示例3:指向常量的常量指针

#include <stdio.h>

int main() {
    int a = 10;
    const int *const p = &a; // 指向和值均不可变

    printf("值: %d\n", *p); // 输出10
    // *p = 20; // 错误!不可修改数据
    // p = NULL; // 错误!不可修改指向
    return 0;
}

示例4:函数参数中的const指针

#include <stdio.h>

// 使用const保护数据不被修改
void print_array(const int *arr, int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
        // arr[i] = 0; // 错误!无法修改数据
    }
    printf("\n");
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    print_array(arr, 5); // 输出1 2 3 4 5
    return 0;
}

三、void指针与const指针的结合使用

#include <stdio.h>

// 泛型打印函数(数据只读)
void print_data(const void *data, char type) {
    switch (type) {
        case 'i':
            printf("整数值: %d\n", *(const int*)data);
            break;
        case 'f':
            printf("浮点值: %.2f\n", *(const float*)data);
            break;
        default:
            printf("未知类型\n");
    }
}

int main() {
    int a = 42;
    float b = 3.14;

    print_data(&a, 'i'); // 输出整数值: 42
    print_data(&b, 'f'); // 输出浮点值: 3.14
    return 0;
}

四、关键总结

注意事项

  • void*转换安全:强制类型转换需确保目标类型正确,否则可能导致数据错误。

  • const保护机制:编译器会检查const约束,违反时会报错。

 


http://www.kler.cn/a/529202.html

相关文章:

  • python-leetcode-相同的树
  • Spring Web MVC基础第一篇
  • LeetCode:279.完全平方数
  • Java的Integer缓存池
  • Linux中 端口被占用如何解决
  • FIDL:Flutter与原生通讯的新姿势,不局限于基础数据类型
  • 【力扣】15.三数之和
  • 网络编程套接字(下)
  • CSS 样式化表格:从基础到高级技巧
  • 快速提升网站收录:利用网站FAQ页面
  • 人工智能入门课【手写自注意力机制】
  • 【回溯】目标和 字母大小全排列
  • 云服务器与Docker
  • 分布式事务组件Seata简介与使用,搭配Nacos统一管理服务端和客户端配置
  • 【华为OD-E卷 - 报数游戏 100分(python、java、c++、js、c)】
  • doris:JSON导入数据
  • Games104——引擎工具链基础
  • Python的那些事第八篇:Python中的类与对象
  • MusicFree-开源的第三方音乐在线播放和下载工具, 支持歌单导入[对标落雪音乐]
  • Nginx知识
  • 什么是Javascript,有什么特点
  • 【cocos官方案例改】跳跃牢猫
  • 【VUE】简述Vue中mixin、extends 的覆盖逻辑
  • NLP深度学习 DAY5:Sequence-to-sequence 模型详解
  • MySQL复制扩展功能
  • AI基本概念之——张量(Tensor)