`
lovnet
  • 浏览: 6944198 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

我只负责转换![C/C++]

阅读更多

我只负责转换![C/C++]

Written by Allen Lee

前不久,lsp在这里留下这样一个问题:

说明:

1.定义了一个枚举如下:

enum_jb_prog_mode
{
PROGRAM_ONE
=0,
PROGRAM_TWO
}
;

enum_jb_prog_modee_prog_index;

2.疑惑:

e_prog_index=(enum_jb_prog_mode)-1;

e_prog_index等于-1?为什么?

你的疑惑隐藏着这样一个结论:e_prog_index的值不应该等于-1。我相信你得出这个结论的理由是_jb_prog_mode枚举中没有哪个成员的值为-1,于是类型为_jb_prog_mode的变量e_prog_index的值也不应该为-1。

现在,我们转换一下场景,假定注册表中有如下的信息:

[HKEY_LOCAL_MACHINE\SOFTWARE\Allen]
"Name"="Allen Lee"
"ID"=dword:00000584

我们如何通过编程获取这些信息呢?我们可以使用Win32 API的RegQueryValueEx()函数来读取这些信息(代码片断):

LPBYTElpData;
DWORDdataBufLen;

if(RegQueryValueEx(hKey,//hKey为指向HKEY_LOCAL_MACHINE\SOFTWARE\Allen的句柄
"Name",
NULL,
NULL,
lpData,
&dataBufLen)==ERROR_SUCCESS)
{
//Convert_01:
char*data=newchar[dataBufLen];
data
=(char*)lpData;
std::cout
"Username:"datastd::endl;


//Convert_02:
//DWORD*data=(DWORD*)lpData;
//std::cout
}


if(RegQueryValueEx(hKey,
"ID",
NULL,
NULL,
lpData,
&dataBufLen)==ERROR_SUCCESS)
{
//Convert_03:
DWORD*data=(DWORD*)lpData;
std::cout
"UserID:"*datastd::endl;

//Convert_04:
//char*data=newchar[dataBufLen];
//char*data=(char*)lpData;
//std::cout
}

留意这段代码有两次转换,如果我们分别把Convert_01和Convert_03替换为Convert_02和Convert_04的话会怎么样呢?编译器不会为难你的,但运行效果可想而知。

回顾这两个例子,我们可以得到什么结论呢?正如本文的题目——

我只负责转换!

当你强制把-1转换为_jb_prog_mode类型并赋值予e_prog_index变量时,你只能说e_prog_index变量不包含_jb_prog_mode枚举预定义的值,并不能说e_prog_index变量的值非法(其实枚举类型和整数类型之间有着很深的渊源)。编译器是不会妨碍你的这种转换,而这种转换是否有意义就是另外一回事了。当然,你应该采取某些措施来检测枚举变量是否包含预定义的值,否则你将可能不时收到意外惊喜。

在C/C++中,枚举其实是整数常量的一种表现形式,它实质上只是协助程序员标识一组相关的整数常量。语义上,

enum_jb_prog_mode
{
PROGRAM_ONE=0,
PROGRAM_TWO
}
;

等效于

staticconstintPROGRAM_ONE=0;
staticconstintPROGRAM_TWO=1;

C/C++给予程序员最大的自由来进行选择,这也体现出C/C++对程序员的信任。然而,这种信任究竟是帮助我们还是伤害我们,就要看程序员本身的做法了。

最后,我引用Robert B. Murray的一段话[1]结束本文:

写出依赖于语言中定义含糊、意义微妙的规则的程序是不好的,即便作者本人清楚它的意义并保证它可以正确运行,下一个来维护这段代码的人也可能未必能够做到这点。比较好的做法是:坚持使用语言中那些被广泛使用及理解的部分来写程序。

See also:


分享到:
评论

相关推荐

    Borland C/C++ 3.1精简版

    例如,`bcc32.exe`是Borland C/C++的命令行编译器,用于将源代码转换成可执行文件;`tds.exe`是调试器,帮助开发者找出程序中的错误;还有`ilink32.exe`,这是链接器,负责将编译后的对象文件与库文件结合生成最终的...

    Android Binder C/C++层实现示例

    本示例"Android Binder C/C++层实现示例"着重展示了如何在C/C++层面进行Binder通信的实现,这对于深入理解Android系统的底层工作原理至关重要。 一、Binder架构 Binder架构包括Client、Server、Service Manager和...

    MATLAB与C/C++、FORTRAN语言混合编程[整理].pdf

    在IT行业中,混合编程是一种常见的...例如,MATLAB可以用于数据预处理、后处理和图形用户界面设计,而C/C++和FORTRAN则负责底层的高性能计算。通过熟练掌握这种编程模式,开发者可以创建出更强大、更高效的软件系统。

    Turbo C/C++ V3.0 C语言编程工具

    编译器将源代码转换为机器码,而链接器则负责处理库引用和生成可执行文件。调试器是学习和优化代码的重要工具,它可以设置断点、查看变量值、单步执行等,帮助开发者理解和修复程序中的错误。 C语言作为基础的系统...

    C/C++语言课程设计

    【C/C++语言课程设计】是一项常见的编程实践任务,旨在帮助学生深入理解编程语言的原理和应用。在这个项目中,作者使用了Visual C++ 6.0(简称VC6.0)作为开发环境,设计了一个结合文件加密和通信录功能的程序。 ...

    C/C++经典笔试题汇总

    ### C/C++经典笔试题汇总知识点解析 #### 题目一:单向链表的反转 **知识点:** 1. **链表基础知识**:理解单向链表的基本结构(包含节点、节点间的链接关系等)。 2. **迭代反转算法**:掌握如何通过迭代方式实现...

    C/C++语言写的词法分析器

    在这个项目中,我们讨论的是一个用C/C++语言编写的词法分析器,这个程序已经成功地完成了编译过程,表明它是可执行的。 在编译器设计中,词法分析器通常由扫描器(Scanner)或词法规则(Lexical Grammar)来实现。...

    OPC UA C/C++协议栈及OPC UA服务器实例

    协议栈中的这部分负责将应用程序的数据转换为网络格式,并将接收到的数据解析回原始形式。 对于OPC UA服务器实例,开发者通常需要以下步骤来创建一个基本的OPC UA服务器: 1. **配置服务器信息**:设置服务器的...

    嵌入式C/C++语言精华

    `extern "C"`是一个C++的关键字,用于告诉编译器按照C语言的方式处理链接,这在C和C++混合编程时尤为重要。由于C++支持函数重载,编译器会对函数名进行修饰,以区分具有相同名字但参数不同的函数,这一过程称为名称...

    C/C++语言文件逆向

    本话题聚焦于使用C/C++进行文件逆向转换,这涉及到编程、文件操作、系统调用等多个方面。下面将详细讨论相关知识点。 1. **C/C++语言基础**:C/C++是两种底层编程语言,它们提供了对计算机硬件的直接访问,使得...

    C/C++编写跨平台程序:实践篇

    ### C/C++编写跨平台程序的关键知识点 #### 一、选择C/C++作为跨平台编程语言的原因 在众多编程语言中,C/C++因其强大的功能和广泛的系统支持而成为跨平台编程的理想选择。正如文中所述,不同的操作系统如Windows...

    android C/C++ JNI普通数据类型 测试工程

    在本文中,我们将深入探讨JNI中的数据类型转换以及如何在C/C++代码和Java代码之间使用它们。 首先,JNI提供了一套与Java数据类型相对应的C数据类型。例如,Java的`int`在JNI中对应的是`jint`,`float`对应`jfloat`...

    francis_flex_C/C++_alivefbc_compiler_

    标题 "francis_flex_C/C++_alivefbc_compiler_" 指示我们讨论的是一款基于 flex 和 yacc 工具构建的 C/C++ 语言编译器,名为 "alivefbc"。这款编译器可能由 Francis 创建,用于解析和编译 C 或 C++ 代码。下面我们将...

    C/C++ 计算日出日落时间

    在IT领域,编程语言C和C++是基石,它们被广泛用于系统编程、游戏开发、高性能计算等场景。本项目专注于使用C/C++来计算日出日落时间,这是一个涉及天文学和地理学的实用问题,对于户外活动、农业、航海等领域都有...

    电池测量C代码,电池检测代码,C/C++

    在这个项目中,我们关注的是使用C语言实现电池检测的代码,这是一种基于C/C++编程语言的技术,用于监测电池的状态,包括电量、电压、电流等关键指标。 首先,我们要理解电量计的概念。电量计,也称为电池管理系统...

    C/C++嵌入式开发编程C/C++嵌入式开发编程C/C++嵌入式开发编程

    - **编译器**:如GCC (GNU Compiler Collection) 是最常用的C/C++编译器之一,能够将源代码转换成机器码。 - **链接器**:负责将多个目标文件连接成可执行文件或库文件。 - **调试器**:如GDB (GNU Debugger),可以...

    C/C++ 动态库嵌套调用源代码文件

    在C/C++编程中,动态库(Dynamic Link Library, DLL)是一种重要的技术,它允许将可执行代码分离到单独的模块中,以便多个程序可以共享同一份代码,从而节省内存和提升性能。动态库的嵌套调用是指一个动态库在运行时...

    编译原理 语法分析 C/C++

    2. **C/C++的语法规则**:C/C++的语法基于C语言,但C++增加了面向对象的特性,如类、模板等。它们的语法严谨且复杂,包含了变量声明、函数定义、控制流语句、类型系统等多个方面。语法分析器需要正确识别这些结构,...

Global site tag (gtag.js) - Google Analytics