热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

区分0的4种面孔

2019独角兽企业重金招聘Python工程师标准0在CC语言中绝对是个多面手,它扮演着多样的角色,拥有着多种面孔。总结起来包括以下几种角色

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

0在C/C++语言中绝对是个多面手,它扮演着多样的角色,拥有着多种面孔。总结起来包括以下几种角色:整型0、空指针NULL、字符串结束标志‘\0’、逻辑FALSE/false,不同的角色适用于不同的情形,下面我们按照上述顺序一一介绍。

这是我们最熟悉的一个角色。作为一个int 类型,整型0 占据32 位的空间,其二进制表示为:

00000000 00000000 00000000 00000000

它的使用方式最为简单直接,未经修饰,如下所示:
int nNum = 0; // 赋值
if( nNum == 0 ) // 比较

空指针NULL
NULL 是一个表示空指针常量的宏,在C/C++ 标准中有如下阐述:
在文件 或者 中定义的NULL 宏,在国际标准中被认为是C++ 空指针常量。指针与int 类型所占空间是一样的,都是32 位。那么,空指针NULL 与0 又有什么区别呢?还是让我们看一下windef.h 中NULL 的定义吧:
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

通过定义我们可以看出,它们之间其实是没有太大的区别,只不过在C 语言中定义
NULL 时会进行一次强制转型。

需要注意的是,这里的0 与整型的0 还是存在区别的。例如,int* pValue = 0; 是合法的,而int* pValue = 1; 则是不合法的。这是因为0 可以用来表示地址,但常数1 绝对不行。

作为指针类型时,推荐按照下面的方式使用0:
float* pNum = NULL; // 赋值
if( pNum == NULL ) // 比较

字符串结束标志'\0'
'\0' 与上述两种情形有所不同,它是一个字符。作为字符,它仅仅占8 位,其二进制表示为:
00000000

因为字符类型中并没有与0000 0000 对应的字符,所以就创造出了这么一个特殊字符。(对于类似'\0' 这样的特殊字符,我们称之为转义字符。)在C/C++ 中,'\0' 被作为字符串结束标志来使用,具有唯一性,与'0' 是有区别的。

作为字符串结束符,0 的使用有些特殊。不必显式地为字符串赋值,但是必须明确字符串的大小。例如,在下面的代码中,“Hello C/C++”只有11 个字符,却要分配12 个字符的空间。
char sHello[12] = {"Hello C/C++"}; // 赋值
if( sHello[11] == '\0' ) // 比较

逻辑FALSE/false
虽然将FALSE/false 放在了一起,但是你必须清楚FALSE 和false 之间不只是大小写这么简单的差别。false/true 是标准C++ 语言里新增的关键字,而FALSE/TRUE 是通过#define 定义的宏,用来解决程序在C 与C++ 环境中的差异。以下是FALSE/TRUE 在windef.h 中的定义:
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif

换言之,FALSE/TRUE 是int 类型,而false/true 是bool 类型,两者是不一样的,只不过C++ 帮我们完成了相关的隐式转换,以至于我们在使用中没有任何感觉。bool 在C++ 里占用的是1 个字节,所以false 也只占用1 个字节。
其二进制表示如下:
false -> 0
FALSE -> 00000000 00000000 00000000 00000000

在C++ 中,推荐使用bool 类型的false/true,其使用方式如下:
bool isReady = false; // 赋值
if( isReady ) // 判断
如果不够细心,0 的多重性可能会让程序产生一些难以发现的Bug,比如:

// 把pSrc 指向的源字符串复制到pDes 指向的内存块
while(pSrc)
{
* pDes ++ = * pSrc ++;
}

正常情况下,当pSrc 指向的字符为字符串结束符'\0' 时,while 循环终止;但不幸的是,这里的条件写错了,while 终止条件变成了pSrc 指向地址0。结果while 循环写入到内存中了,直至程序崩溃。
正确的写法应该是:

while(*pSrc)
{

* pDes ++ = * pSrc ++;


}

 


转:https://my.oschina.net/u/245046/blog/55406



推荐阅读
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Python语法上的区别及注意事项
    本文介绍了Python2x和Python3x在语法上的区别,包括print语句的变化、除法运算结果的不同、raw_input函数的替代、class写法的变化等。同时还介绍了Python脚本的解释程序的指定方法,以及在不同版本的Python中如何执行脚本。对于想要学习Python的人来说,本文提供了一些注意事项和技巧。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了Linux Shell中括号和整数扩展的使用方法,包括命令组、命令替换、初始化数组以及算术表达式和逻辑判断的相关内容。括号中的命令将会在新开的子shell中顺序执行,括号中的变量不能被脚本余下的部分使用。命令替换可以用于将命令的标准输出作为另一个命令的输入。括号中的运算符和表达式符合C语言运算规则,可以用在整数扩展中进行算术计算和逻辑判断。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
author-avatar
黄欣豪972
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有