C语言高手都在用的void*指针转换秘诀(资深工程师20年经验总结)

C语言关键字深度解析:从static、volatile到模块化编程实战 在C语言编程中,数据类型、存储类别和流程控制是构建程序的基础。数据类型关键字如int、char定义了数据的存储格式,而存储类别关键字如static、extern则决定了变量的生命周期与作用域,这是理解程序内存布局的关键。深入掌握这些概念,能显著提升代码的效率和可维护性,尤其在嵌入式系统开发中,对volatile关键字的正确使用,能确保程序与硬件寄存器的可靠交互。本文聚焦于static、const、volatile等核心关键字,通过模块化编程、多线程同步等典型应用场景,剖析其底层原理与实战技巧,帮助开发者避免 阅读详情

第一章:void*指针的本质与核心地位

什么是void*指针

在C和C++语言中,void* 是一种特殊的指针类型,表示“指向未知类型的指针”。它不关联任何具体数据类型,因此不能直接解引用。这种指针的核心价值在于其通用性,能够临时存储任意类型对象的地址,常用于底层内存操作、系统接口设计以及泛型编程场景。

void*的典型应用场景

  • 动态内存分配函数如 malloc 返回 void*,以便适配任意类型需求
  • 函数参数中使用 void* 实现回调机制或数据透传
  • 跨模块通信时传递未确定结构的数据块

使用示例与注意事项

以下代码展示了如何安全地使用 void* 进行内存操作:


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

int main() {
    int value = 42;
    void *ptr = &value;  // 指向int类型的地址

    // 必须显式转换回原类型才能正确访问
    int *int_ptr = (int*)ptr;
    printf("Value: %d\n", *int_ptr);

    return 0;
}

执行逻辑说明:先将整型变量地址赋给 void* 指针,随后通过强制类型转换还原为原始指针类型进行解引用。若未转换而直接解引用,将导致编译错误。

void*与其他指针的兼容性

源指针类型能否赋值给void*是否需要显式转换
int*是否(自动转换)
char*是否
void*自身否

第二章:void*指针转换的基本规则与语法机制

2.1 void*的类型自由性与内存抽象原理

void* 是C/C++中一种特殊的指针类型,表示“指向未知类型的指针”。它不绑定任何具体数据类型,因此可以临时存储任意类型对象的地址,实现内存层面的通用访问。

类型自由性的体现
  • 可接受任意类型指针的赋值,如 int*、char*
  • 在强制类型转换后恢复原始类型,保持数据语义完整
  • 广泛用于泛型编程接口,如 qsort 和 bsearch
内存抽象的核心机制
void swap(void* a, void* b, size_t size) {
    char* temp = (char*)malloc(size);
    memcpy(temp, a, size);      // 按字节复制内存
    memcpy(a, b, size);
    memcpy(b, temp, size);
    free(temp);
}

该函数通过 void* 接收任意类型的地址,并结合 size 参数明确内存块大小,利用字节级操作实现通用交换。这种设计将逻辑与具体类型解耦,体现了底层内存抽象的思想。

2.2 标准规定下的合法转换路径解析

在类型系统设计中,合法的类型转换必须遵循语言标准定义的隐式与显式规则。这些规则确保了数据完整性与程序安全性。
隐式转换路径
多数静态类型语言允许安全的窄向宽类型转换,例如从 int 到 long:

int a = 100;
long b = a; // 合法:标准规定的提升转换
该转换由标准保证无精度损失,编译器自动插入类型提升指令。
显式转换约束
强制类型转换需满足可转换性条件,C++ 使用 static_cast 明确语义:

double x = 3.14;
int y = static_cast<int>(x); // 截断小数部分
此操作虽合法,但可能丢失精度,需开发者显式确认意图。
源类型目标类型是否合法
floatdouble是(精度提升)
boolint是(true→1, false→0)
void*int*需显式转换

2.3 指针赋值中的隐式与显式转换实践

在指针操作中,类型转换是常见需求。Go语言禁止隐式指针类型转换,必须通过显式方式完成,以确保内存安全。
显式转换的基本模式

var a int = 42
var pa *int = &a
var pb *int32 = (*int32)(unsafe.Pointer(pa)) // 显式转换
上述代码通过 unsafe.Pointer 实现不同指针类型的转换。首先将 *int 转为 unsafe.Pointer,再转为目标类型 *int32。这种双层转换是Go中跨类型指针操作的合法路径。
常见转换场景对比
场景是否允许说明
*int → *int64否(隐式)类型不兼容,需显式转换
*struct → unsafe.Pointer是通用指针过渡步骤
nil 赋值任意指针是nil 可隐式适配所有指针类型

2.4 不同数据类型间转换的对齐与兼容性分析

在跨系统数据交互中,类型转换的对齐机制直接影响数据完整性。不同编程语言和存储格式对基本类型的字节序、精度和范围定义存在差异,需通过标准化映射确保语义一致。
常见数据类型映射关系
源类型(Java)目标类型(JSON)转换规则
intnumber直接序列化为整数
booleanboolean保留原始布尔值
StringstringUTF-8编码传输
浮点数转换示例
// 将float64转为JSON兼容格式
func ConvertFloat(f float64) interface{} {
    if math.IsNaN(f) || math.IsInf(f, 0) {
        return nil // JSON不支持NaN/Inf
    }
    return f
}
该函数处理了IEEE 754特殊值,在序列化前进行校验,避免因浮点异常导致解析失败,体现了类型兼容性控制的关键路径。

2.5 常见编译器对void*转换的行为差异实测

在C语言中,void*作为通用指针类型,理论上可隐式转换为任意对象指针类型。然而不同编译器对此类转换的严格程度存在差异。
测试环境与编译器版本
  • GCC 11.4.0(Linux)
  • Clang 14.0.6(Linux)
  • MSVC 19.33(Windows)
典型代码行为对比

int main() {
    void *ptr = malloc(sizeof(int));
    int *iptr = ptr;        // 是否报错?
    return 0;
}
GCC和Clang在默认C标准下允许该隐式转换,而MSVC在/C/Zc:strictStrings模式下会发出警告或错误。
行为差异汇总
编译器标准模式是否允许隐式转换
GCCC99是
ClangC11是
MSVCC11否(需显式转换)
此差异要求跨平台开发时显式转换void*以确保兼容性。

第三章:void*在函数参数与返回值中的高级应用

3.1 通用接口设计:memcpy与qsort背后的指针魔法

在C语言中,`memcpy`和`qsort`是通用接口设计的典范,其核心在于对void指针的灵活运用。通过不指定具体类型,这些函数能够处理任意数据类型,实现高度复用。
void指针的通用性
`void*`可指向任何数据类型,在运行时通过字节偏移进行访问。这种“类型擦除”机制是通用性的基础。

void *memcpy(void *dest, const void *src, size_t n) {
    char *d = (char *)dest;
    const char *s = (const char *)src;
    for (size_t i = 0; i < n; i++) {
        d[i] = s[i];
    }
    return dest;
}
该代码将`void*`强制转换为`char*`,以字节为单位复制内存,不受类型限制。
回调函数与数据抽象
`qsort`通过函数指针比较元素:

int compare(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}
传入`qsort`的比较函数接收`void*`参数,由用户定义具体类型的解析方式,实现排序逻辑与数据类型的解耦。

3.2 回调机制中void*传递用户数据的实战模式

在C/C++系统编程中,回调函数常用于事件处理与异步操作。为增强回调的通用性,通常使用 void* 参数传递用户自定义数据,实现上下文透传。
通用回调函数设计

typedef void (*callback_t)(void* user_data);

void event_handler(void* user_data) {
    int* value = (int*)user_data;
    printf("Received data: %d\n", *value);
}
上述代码定义了接收 void* 的回调函数。调用时可传入任意类型地址,解引用前需确保类型一致性。
实际应用场景
  • 多线程任务中传递线程私有数据
  • 库函数注册钩子时携带上下文信息
  • 事件循环中关联对象实例
通过 void* 机制,实现了回调逻辑与数据解耦,提升接口灵活性和复用性。

3.3 构建可复用库函数时的安全转换规范

在开发通用库函数时,类型安全与数据完整性是首要考量。不严谨的类型转换可能导致运行时崩溃或逻辑错误,尤其在跨平台或多人协作场景中更为敏感。
类型转换的边界控制
应始终对输入参数进行校验,并限制转换范围。例如,在 Go 中将 int64 转为 int32 时需防止溢出:
func safeInt64ToInt32(value int64) (int32, bool) {
    if value < math.MinInt32 || value > math.MaxInt32 {
        return 0, false
    }
    return int32(value), true
}
该函数通过预判数值范围确保转换合法性,返回布尔值标识操作是否成功,提升调用方处理异常的能力。
统一转换接口设计
推荐使用接口抽象转换逻辑,便于扩展和测试。常见做法包括定义 Converter 接口并实现标准化方法,降低耦合度。

第四章:典型场景下的void*转换陷阱与规避策略

4.1 类型丢失导致的运行时错误深度剖析

在动态类型语言或类型擦除机制中,类型信息可能在编译后丢失,导致运行时无法正确判断数据结构,从而引发严重错误。
典型场景:泛型类型擦除
Java 中的泛型在编译期进行类型擦除,所有泛型类型信息被替换为原始类型:

List<String> strings = new ArrayList<>();
List<Integer> integers = new ArrayList<>();

System.out.println(strings.getClass() == integers.getClass()); // 输出 true
上述代码中,strings 和 integers 在运行时均为 ArrayList 类型,原始泛型信息已丢失,无法通过 instanceof 进行类型区分。
后果与防范策略
  • 类型转换异常(ClassCastException)在运行时才暴露
  • 反射操作难以获取真实泛型参数
  • 建议使用类型令牌(TypeToken)或封装类保留类型信息

4.2 结构体指针与void*互转的正确姿势

在C语言中,结构体指针与void*的转换广泛应用于通用接口设计。转换时必须确保类型安全与内存对齐。
基本转换原则
void*可接收任意指针类型,但反向转换需显式强制类型转换:

typedef struct {
    int id;
    char name[32];
} Person;

Person p = {1, "Alice"};
void* vp = &p;           // 隐式转换
Person* pp = (Person*)vp; // 显式还原
上述代码中,vp = &p无需强制转换,但还原为结构体指针时必须明确指定类型,否则编译器无法推断原始结构布局。
常见错误与规避
  • 未强制转换导致编译警告或运行时异常
  • 跨平台对齐差异引发内存访问错误
建议始终使用assert(sizeof(T))验证结构大小,并避免在void*间多重间接转换。

4.3 数组与动态内存管理中的void*使用禁忌

在C语言中,void*常被用于通用指针操作,但在数组与动态内存管理中存在若干使用禁忌。
避免对void*进行指针算术运算
void*不指向具体类型,编译器无法确定步长,因此不能直接进行递增或偏移操作。

void *ptr = malloc(10 * sizeof(int));
// 错误:void* 无法参与指针算术
// ptr++; // 编译错误或未定义行为

// 正确做法:转换为具体类型
int *iptr = (int*)ptr;
iptr++;
上述代码展示了为何必须将void*转换为具体类型后才能进行地址运算。
常见陷阱总结
  • 对void*执行sizeof(*ptr)将导致编译错误
  • 在realloc后未重新赋值可能导致悬空指针
  • 类型转换时未校验原始数据类型,引发内存解析错误

4.4 多线程环境下void*参数传递的风险控制

在多线程编程中,通过 void* 传递参数虽灵活,但易引发内存竞争与生命周期问题。若多个线程共享同一指针,而原始数据提前释放,将导致悬空指针。
常见风险场景
  • 主线程栈变量被子线程异步访问
  • 动态分配内存未正确同步释放时机
  • 类型转换错误引发数据解释偏差
安全传递示例

typedef struct {
    int id;
    char *data;
} ThreadArg;

void* thread_func(void* arg) {
    ThreadArg* my_arg = (ThreadArg*)arg;
    printf("ID: %d\n", my_arg->id); // 安全访问
    free(my_arg); // 自主管理生命周期
    return NULL;
}
上述代码通过堆分配结构体并由子线程自行释放,避免了栈变量失效问题。参数封装明确,提升类型安全性。
推荐控制策略
策略说明
堆内存传递确保数据生命周期覆盖线程执行期
引用计数多线程共享时防止过早释放

第五章:从经验到直觉——成为C语言指针掌控者

理解指针的本质
指针并非神秘的语法糖,而是内存地址的直接映射。熟练掌握指针意味着能精确控制数据在内存中的布局与访问方式。例如,在处理大型结构体时,使用指针传递可避免栈溢出:

typedef struct {
    int data[1000];
} LargeStruct;

void process(LargeStruct *ptr) {
    // 直接操作原始内存,避免复制开销
    ptr->data[0] = 42;
}
动态内存管理实战
合理使用 malloc 和 free 是构建灵活程序的基础。以下为动态数组创建示例:

int *arr = (int*)malloc(10 * sizeof(int));
if (!arr) {
    fprintf(stderr, "Memory allocation failed\n");
    exit(1);
}
arr[0] = 10;
free(arr); // 防止内存泄漏
  • 始终检查 malloc 返回值
  • 确保 free 与 malloc 成对出现
  • 避免对同一指针多次释放
函数指针的应用场景
函数指针实现回调机制,广泛应用于事件驱动系统。例如,定义一个排序函数接受比较逻辑:

int compare_asc(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

qsort(array, n, sizeof(int), compare_asc);
指针类型典型用途
int *遍历整型数组
char **处理命令行参数 argv
void (*)()注册中断服务例程
C#性能真相:CLR运行时与JIT优化的工程权衡指南 编程语言性能并非简单快慢之分,而是运行时环境、编译策略与工程场景的系统性协同。.NET的CLR提供托管内存、自动垃圾回收和Just-In-Time(JIT)动态编译机制,使C#在长期运行稳定性、安全边界保障和CPU指令级自适应优化(如AVX/SSE内联数学函数)上具备独特优势;其性能价值不体现在冷启动微基准,而在于真实服务中的稳态吞吐、GC可控性与开发运维综合效率。典型应用场景包括高并发Web API、工业物联网网关(协同C++计算核心)、实时数据处理管道等。理解JIT编译开销、托管堆行为与Benchmar 阅读详情

相关推荐

地瓜机器人RDK Studio使用入门教程

不知道大家在使用AI开发板的时候有没有遇到过板子官方镜像占据空间大难以保存,想要的时候找不到?官方示例项目久而久之便难以找寻?首次登陆开发板连接网络还需要准备显示器键盘鼠标外设繁杂?…为了解决平时开发过程中遇到的种种不便利问题,地瓜机器人创新的推出了RDK Studio这一官方开发者软件,使智能机器人开发迎来新纪元!通过这一软件极大降低了机器人的开发门槛,哪怕是零基础的用户亦可轻松上手RDK系列板卡!

xiongqi123123的博客 3427

C++类型转换总结

一、隐式转换 这样的转换也可以叫做隐式转换,类似 小的类型转为大的类型int i = 10; double j = i;此时隐式将Int类型转换成了double类型。 二、显式转换 double j = 10.0; int i = int(j); 三、static_cast关键字(编译时类型检查) 用法:static_cast<type_id>(expression),改运算符把e...

Jack的博客 683

使用pytorch构建LSTM_AE模型的两种方式

2.基本LSTM_Unit计算——基本LSTM_AE结构 3.自定义LSTM_Unit计算——自定义LSTM_AE结构 1.LSTM-Encoder-Decoder模型结构及简要解析 图基本lstm计算单元

qq_37840762的博客 7274

C++强制类型转换规则(void*)

想要将void*转换为int*,c语言可以直接写"p=q",但在C++中这是不允许的;所以在C++中想要将void*转换为int*,可以使用p=static_cast。而反过来,想要将int*转换为void*,在C++中就可以直接写"q=p";

weixin_44050362的博客 2807

Robocopy 参数进阶:/MIR 镜像同步与 /PURGE 删除操作的风险规避指南

本文深入解析Robocopy的/MIR镜像同步与/PURGE删除操作的高级用法及风险规避策略。通过实际案例和四重防护机制,指导用户安全实现目录同步,避免数据丢失风险,特别适用于远程主机间的数据复制与备份场景。

weixin_33462927的博客 356

2.13寸电子墨水屏HINK-E0213+esp8266

很久以前买的一块电子墨水屏,运气很好,这个型号HINK-E0213资料很全,而且微雪官网也有相关电路资料等。

梦境虽美,却不长. 3003

C++高级使用技巧:强制类型转换

在C语言中,如果表达式赋值运算符左右两侧变量或表达式的数据类型不同,或者形参变量与实参变量类型不匹配,或者返回值变量类型与接收值类型不一致时,就需要进行类型转化,C++语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换。隐式类型转化是编译器在自动进行,能转就转,不能转就会发生编译失败;而显式类型转化(强转)是用户自己进行类型转换操作。

qq_36756667的博客 719

风力摆控制系统 PCB 设计 3 要点:STM32+MPU6050+空心杯电机驱动一体化

本文详细解析了风力摆控制系统PCB设计的3大核心要点,重点介绍STM32主控、MPU6050姿态传感器与空心杯电机驱动的一体化方案。通过系统架构设计、PCB布局布线技巧以及噪声抑制方案,帮助参赛者在电子设计竞赛中构建高精度、高稳定性的风力摆控制系统,提升竞赛作品性能。

weixin_30363285的博客 359

C++通过指针调用其他类的函数,void*指针强转为对象类型调用

类的实现中需要使用其他类的某个函数时,通常可以采用实例对象的方法,但是当两个类依赖很深,互相关联的时候的,这么操作往往会有瑕疵。如果B中创建A的对象实例,那么就会初试化改变全局变量的值,所以用这种方法会导致错误,我们不希望全局变量再次被初始化。例如:类A中某函数需要用到类B的实例对象,而类B又需要A的某个函数,但是A和B都用到了一个。此时B的useA()函数需要使用A的hello()函数,如果是直接用A的对象。类A初始化了全局变量str,类A中创建了B的对象,B的对象修改了str。首先在B中定义了一个。

西叶胡杨的博客 2196

Vue+OpenLayers7入门到实战目录,OpenLayers7中文文档,OpenLayers7中文手册,OpenLayers7中文教程,OpenLayers7文档pdf

本篇作为《Vue+OpenLayers7入门到实战》所有文章的二合一汇总目录,方便查找。本专栏源码是由OpenLayers7.x版本结合Vue框架编写。本专栏从Vue搭建脚手架到如何引入OpenLayers7依赖的每一步详细新手教程,再到通过各种入门案例和综合性的实战案例,带领大家快速上手Vue+OpenLayers7开发。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 3971

YOLOv11改进,YOLOv11引入B2CNet的BFAM(双时相特征聚合模块),JSTARS 2024,二次创新C3k2结构

YOLOv11改进,YOLOv11引入B2CNet的BFAM(双时相特征聚合模块),JSTARS 2024,二次创新C3k2结构

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 406

C++:基础类型转换

1、结构体 转 void* struct A {}; A a; void * b = (void *)&amp;amp;amp;amp;a; 2、const void* 转 void* const void* pConstVoid; (1) 首先用const_cast转换将const void*的const属性去掉 void* pChar = const_cast&amp;amp;amp;lt;void*&amp;amp;amp;gt;(pConstVoid

木头 1250

利用SIMULINK搭建一个16QAM调制解调收发系统

1发送模块设计 根据前面介绍的理论知识,我们可以知道16QAM的基本结构,首先我来设计QAM发送段的SIMULINK仿真模块。 图1 16QAM的发送端模块 他的基本工作流程为:将信号通过两路升余弦滤波器,得到滤波以后的信号,滤波器的作用就是为了防止码间干扰。然后将滤波以后的信号和SIN,COS相乘得到调制信号,将调制 下面一一介绍每个模块的具体参数设置以及各个部分信号的波形图。 图2 产生随机数据的信号源 第一部分信号是产生一组随机的数字,作为信源,第二个模块将信号...

FPGA/MATLAB学习教程/源码/项目合作开发 4776

ZeroMQ高性能网络编程与C/C++优化实战指南

网络通信是分布式系统的基础,其核心在于高效、可靠的数据传输。消息队列作为解耦系统组件、实现异步通信的关键技术,通过预定义的通信模式简化了复杂网络编程。在底层实现中,零拷贝机制通过避免不必要的数据复制,显著提升了传输效率,尤其适合高吞吐场景。结合C/C++语言特性,开发者可以进一步优化内存管理和并发模型,例如通过自定义内存池减少动态分配开销,利用多线程与无锁数据结构提升处理能力。这些优化手段在金融交易、实时游戏、物联网等对延迟敏感的应用场景中价值显著。本文以ZeroMQ为例,深入探讨如何将其零拷贝特性与C/C

weixin_33778544的博客 421

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Java团队如何用Ollama实现大模型本地化集成

大模型本地部署是企业级AI落地的关键环节,其核心在于推理运行时与业务系统的低耦合集成。Ollama作为轻量级、OpenAI兼容的模型服务框架,凭借Go语言实现的稳定显存管理、标准HTTP/SSE接口及Unix哲学设计,成为Java技术栈的理想适配层。相比VLLM或Dify等重型平台,Ollama规避了JVM GC干扰GPU、协议黑盒、运维不可控等工程风险,使Spring Boot能以WebClient原生调用方式完成流式响应、熔断限流与全链路监控。本文聚焦Java工程师可掌控的实战路径:CentOS环境下的

369

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

c++ void*类型转换 delete void*

1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int N=1e5+10; 5 const int INF=0x3f3f3f3f; 6 int cas=1,T; 7 struct node{ 8 int *p; 9 ...

weixin_30685047的博客 570

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C++开发基础之了解void*类型的指针用法

void*类型是一个通用的指针类型,可以指向任意类型的数据,但它本身不包含任何类型信息。在 C 和 C++ 等编程语言中,void* 类型的指针被用来表示一个未知类型的指针。这种指针的具体用法通常是为了实现一些通用的数据结构或算法,或者在不同类型之间传递指针时的类型安全性问题。在C++中,任何对象的指针都可以转换为void*类型的指针,这种转换称为指针的强制类型转换或隐式转换。这种特性允许将任何类型的指针赋值给void*类型的指针,并且可以通过或者 C 风格的强制转换来实现。

dotnet研习社 1561

C++ void *类型强转为int类型

目录💖 前言💖 问题描述💖 原因分析💖 解决方法💖 补充 💖 前言 C语言允许从void*隐式转换到其它的指针类型,但C++不允许。因为,C++对类型转换要求很高。 💖 问题描述 在linux平台上,进行void * 到int类型强转,出现如下错误: error: cast from ‘void*’ to ‘int’ loses precision [-fpermissive] Demo01代码如下: // Type.cpp #include<iostream> #include<st.

温暖不了你的心的博客 7771

C++ (void *) 强制类型转换

中间想过通过仅声明一个namespace,将其余两个命名空间中整合在一块,就不会出现互相包含引用的关系、还有一个是增加一个参数,将他一层一层递归传到需要用到的地方。3-但因为将后面用到的类,提前在前面引用,所以整个逻辑就像:a中需要声明b中的一个对象,b中需要声明c中的一个对象,c中需要声明a中的一个对象。2-因为整个项目是在多线程下,其中一个命名空间对象需要在某个子线程下运行,static会共享变量所以不可取,所以就在程序开始进行声明。1-有三个命名空间,a、b、c。希望能够为你启发一条新思路。

m0_63837234的博客 338

C/C++中的 void*

在看《Unix/Linux系统编程》中关于POSIX Thread部分的时候发现C语言中用void*传递了int类型变量,很疑惑,于是差了些资料并汇总了一下。 介绍了C语言和C++中关于void*的用法,涉及到了C++中的reinterpret_cast 如果哪里有错误欢迎指正! 参考资料 参考资料 1. C/C++中的void*与其他指针类型转换 1.1 C中void*与其他指针类型转换 C语言对指针类型的转换要求很低。但是这将留下一个很大的漏洞 int* a=NULL; void* b=NULL;

Nick_Di的博客 2280

C++类型转换的陷阱:void*转换的安全隐患与实践

在C++编程中,类型转换是一项常见的操作,尤其是在处理低级别数据操作或多态性时。然而,不当的类型转换可能会引发严重的安全隐患和运行时错误。在本章中,我们将探讨类型转换的需求背景,特别是那些可能导致潜在风险的操作,如将`void*`指针转换为具体类型的指针。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 7208

c++中如何把任意类型的指针转化为void*

C++任意类型指针无损转换为void*

importpygame的博客 2876

C语言回调函数

#include <stdio.h> //函数指针定义 //type (*paramName)() // 实际执行函数 int callback1() { printf("callback1 function\n"); return 1; } // 回调的函数 // 函数指针作为函数参数 int handle(int(*callbackFun)()) { printf("handle enter\n"); int ret = callbackFun(); printf("han.

quietbxj的博客 491

C++中的类型转换

目录 1. 隐式转换 2. 显示转换 3. static_cast(静态转换) 4. dynamic_cast(动态转换) 5. const_cast 6. reinterpret_cast 1. 隐式转换 1)提升精度,宽化转换:(如char到int,int到long long,int到float,float到double,int到double等)构成隐式转换,编译器允许直...

漆灿 609

类型转换

在C++中,可以使用类型来表示任意类型的指针。而是C++标准库中的字符串类型。要在和之间进行转换,需要使用类型转换操作符或者函数。下面是到的转换示例: 在上面的示例中,我们先将一个字符串字面值转换为类型的指针,然后通过函数将转换为类型。最后,我们将该字符串打印到标准输出。下面是到的转换示例: 在上面的示例中,我们首先将一个类型的字符串定义为,然后通过函数将转换为类型。最后,我们将该字符串打印到标准输出。需要注意的是,和之间的转换可能会引发类型不匹配或者内存访问错误等问题,因此在进行转换时需要谨慎处理。表示:

清风 1249

(C\C++)void 类型指针和函数指针(使用详解)

void 数据类型是空的数据类型,表示没有数据类型,void* 空类型指针只存储地址的值,丢失类型,只知道是地址。要访问其值,我们必须对这个指针做出正确的类型转换,然后再可以间接引用指针。可以赋值,在没转换之前不能进行算数运算,其它类型指针转换为void *指针 隐式自动转换,不需要强制转换 也就是赋值: string name="Maike"; void * str = &name; void *类型指针转换为其它类型指针,需要强制类型转换

IDO_Hero的博客 2372
上一篇: 【C语言内存布局深度解析】:全局变量与局部变量究竟存储在哪个区域?
下一篇: 从零实现C语言归并排序:递归思想与代码落地的完美结合
Instrustar
博客等级 码龄1年 182粉丝 2225原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值