服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++11中longlong超长整型和nullptr初始化空指针

C++11中longlong超长整型和nullptr初始化空指针

2023-06-05 14:45crossoverpptx C/C++

本文介绍 C++11 标准中新添加的 long long 超长整型和 nullptr 初始化空指针,在 C++11 标准下,相比 NULL 和 0,使用 nullptr 初始化空指针可以令我们编写的程序更加健壮,本文结合示例代码给大家详细讲解,需要的朋友跟随小编一起看看

本文介绍 C++11 标准中新添加的 long long 超长整型和 nullptr 初始化空指针。

1. C++11:long long 超长整型

C++ 11 标准中,基于整数大小的考虑,共提供了如下表所示的这些数据类型。与此同时,标准中还明确限定了各个数据类型最少占用的位数。

整数类型 等价类型 C++11标准规定占用最少位数
short short int(有符号短整型) 至少 16 位(2 个字节)
signed short short int(有符号短整型) 至少 16 位(2 个字节)
signed short int short int(有符号短整型) 至少 16 位(2 个字节)
unsigned short unsigned short int(无符号短整型) 至少 16 位(2 个字节)
unsigned short int unsigned short int(无符号短整型) 至少 16 位(2 个字节)
int int(有符号整形) 至少 16 位(2 个字节)
signed int(有符号整形) 至少 16 位(2 个字节)
signed int int(有符号整形) 至少 16 位(2 个字节)
unsigned unsigned int(无符号整形) 至少 16 位(2 个字节)
unsigned int unsigned int(无符号整形) 至少 16 位(2 个字节)
long long int(有符号长整形) 至少 32 位(4 个字节)
long int long int(有符号长整形) 至少 32 位(4 个字节)
signed long long int(有符号长整形) 至少 32 位(4 个字节)
signed long int long int(有符号长整形) 至少 32 位(4 个字节)
unsigned long unsigned long int(无符号长整形) 至少 32 位(4 个字节)
unsigned long int unsigned long int(无符号长整形) 至少 32 位(4 个字节)
long long(C++11) long long int(有符号超长整形) 至少 64 位(8 个字节)
long long int(C++11) long long int(有符号超长整形) 至少 64 位(8 个字节)
signed long long(C++11) long long int(有符号超长整形) 至少 64 位(8 个字节)
signed long long int(C++11) long long int(有符号超长整形) 至少 64 位(8 个字节)
unsigned long long(C++11) unsigned long long int(无符号超长整型) 至少 64 位(8 个字节)
unsigned long long int(C++11) unsigned long long int(无符号超长整型) 至少 64 位(8 个字节)

C++11 标准规定,每种整数类型必须同时具备有符号(signed)和无符号(unsigned)两种类型,且每种具体的有符号整形和无符号整形所占用的存储空间(也就是位数)必须相同。不过需要注意的是,C++11 标准中只限定了每种类型最少占用多少存储空间,不同的平台可以占用不同的存储空间。

在上表罗列的这些数据类型中,long long 超长整型是 C++ 11 标准新添加的。其实早在 1995 年,就有人提议将 long long 整形写入 C++ 98 标准,但被委员会拒绝了。而后 long long 整形被 C99 标准(C语言标准之一)采纳,并逐渐被很多编译器支持,于是 C++ 标准委员会重新决定将 long long 整形写入 C++ 11 标准中。

如同 long 类型整数需明确标注 "L" 或者 "l" 后缀一样,要使用 long long 类型的整数,也必须标注对应的后缀:

  • 对于有符号 long long 整形,后缀用 "LL" 或者 "ll" 标识。例如,"10LL" 就表示有符号超长整数 10;
  • 对于无符号 long long 整形,后缀用 "ULL"、"ull"、"Ull" 或者 "uLL" 标识。例如,"10ULL" 就表示无符号超长整数 10。

如果不添加任何标识,则所有的整数都会默认为 int 类型。

对于 long long 类型来说,如果想了解当前平台上 long long 整形的取值范围,可以使用<climits>头文件中与 long long 整形相关的 3 个宏,分别为 LLONG_MIN、LLONG_MAX 和 ULLONG_MIN:
1)LLONG_MIN:代表当前平台上最小的 long long 类型整数;
2)LLONG_MAX:代表当前平台上最大的 long long 类型整数;
3)ULLONG_MIN:代表当前平台上最大的 unsigned long long 类型整数(无符号超长整型的最小值为 0)。
举个例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <iomanip>
#include <climits>
using namespace std;
 
int main()
{
    cout <<"long long最大值:" << LLONG_MIN <<" "<< hex << LLONG_MIN <<"\n";
    cout << dec <<"long long最小值:" << LLONG_MAX << " " << hex << LLONG_MAX << "\n";
    cout << dec << "unsigned long long最大值:" << ULLONG_MAX << " " << hex << ULLONG_MAX;
    return 0;
}

程序执行结果为(不唯一):

?
1
2
3
long long最大值:-9223372036854775808 8000000000000000
long long最小值:9223372036854775807 7fffffffffffffff
unsigned long long最大值:18446744073709551615 ffffffffffffffff

此程序中,输出了各最大值和最小值对应的十六进制,显然在当前平台(Windows10 64位操作系统)上,long long 超长整型占用 64 位(也就是 16 个字节)的存储空间。

2. C++11:nullptr 初始化空指针

实际开发中,避免产生“野指针”最有效的方法,就是在定义指针的同时完成初始化操作,即便该指针的指向尚未明确,也要将其初始化为空指针。

所谓“野指针”,又称“悬挂指针”,指的是没有明确指向的指针。野指针往往指向的是那些不可用的内存区域,这就意味着像操作普通指针那样使用野指针(例如 &p),极可能导致程序发生异常。

C++98/03 标准中,将一个指针初始化为空指针的方式有 2 种:

?
1
2
int *p = 0;
int *p = NULL; //推荐使用

可以看到,我们可以将指针明确指向 0(0x0000 0000)这个内存空间。一方面,明确指针的指向可以避免其成为野指针;另一方面,大多数操作系统都不允许用户对地址为 0 的内存空间执行写操作,若用户在程序中尝试修改其内容,则程序运行会直接报错。
相比第一种方式,我们更习惯将指针初始化为 NULL。值得一提的是,NULL 并不是 C++ 的关键字,它是 C++ 为我们事先定义好的一个宏,并且它的值往往就是字面量 0(#define NULL 0)。

C++ 中将 NULL 定义为字面常量 0,虽然能满足大部分场景的需要,但个别情况下,它会导致程序的运行和我们的预期不符。例如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;
 
void isnull(void *c){
    cout << "void*c" << endl;
}
void isnull(int n){
    cout << "int n" << endl;
}
 
int main() {
    isnull(0);
    isnull(NULL);
    return 0;
}

程序执行结果为:

int n
int n

对于 isnull(0) 来说,显然它真正调用的是参数为整形的 isnull() 函数;而对于 isnull(NULL),我们期望它实际调用的是参数为 void*c 的 isnull() 函数,但观察程序的执行结果不难看出,并不符合我们的预期。
C++ 98/03 标准中,如果我们想令 isnull(NULL) 实际调用的是 isnull(void* c),就需要对 NULL(或者 0)进行强制类型转换:

?
1
2
isnull( (void*)NULL );
isnull( (void*)0 );

如此,才会成功调用我们预期的函数。

由于 C++ 98 标准使用期间,NULL 已经得到了广泛的应用,出于兼容性的考虑,C++11 标准并没有对 NULL 的宏定义做任何修改。为了修正 C++ 存在的这一 BUG,C++ 标准委员会最终决定另其炉灶,在 C++11 标准中引入一个新关键字,即 nullptr。

在使用 nullptr 之前,需保证自己使用的编译器支持该关键字。以 Visual Studio 和 codeblocks 为例,前者早在 2010 版本就对 C++ 11 标准中的部分特性提供了支持,其中就包括 nullptr;如果使用后者,则需将其 G++ 编译器版本至少升级至 4.6.1(同时开启 -std=c++0x 编译选项)。

nullptr 是 nullptr_t 类型的右值常量,专用于初始化空类型指针。nullptr_t 是 C++11 新增加的数据类型,可称为“指针空值类型”。也就是说,nullpter 仅是该类型的一个实例对象(已经定义好,可以直接使用),如果需要我们完全定义出多个同 nullptr 完全一样的实例对象。

值得一提的是,nullptr 可以被隐式转换成任意的指针类型。举个例子:

?
1
2
3
int * a1 = nullptr;
char * a2 = nullptr;
double * a3 = nullptr;

显然,不同类型的指针变量都可以使用 nullptr 来初始化,编译器分别将 nullptr 隐式转换成 int*、char* 以及 double* 指针类型。

另外,通过将指针初始化为 nullptr,可以很好地解决 NULL 遗留的问题,比如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;
 
void isnull(void *c){
    cout << "void*c" << endl;
}
void isnull(int n){
    cout << "int n" << endl;
}
 
int main() {
    isnull(NULL);
    isnull(nullptr);
    return 0;
}

程序执行结果为:

int n
void*c

借助执行结果不难看出,由于 nullptr 无法隐式转换为整形,而可以隐式匹配指针类型,因此执行结果和我们的预期相符。

总之在 C++11 标准下,相比 NULL 和 0,使用 nullptr 初始化空指针可以令我们编写的程序更加健壮。

到此这篇关于C++11:longlong超长整型和nullptr初始化空指针的文章就介绍到这了,更多相关C++11 nullptr初始化空指针内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/crossoverpptx/archive/2022/12/31/17016228.html

延伸 · 阅读

精彩推荐
  • C/C++详解C语言初阶基础

    详解C语言初阶基础

    这篇文章主要介绍了C语言中的初阶基础,介绍了其相关概念,具有一定参考价值。需要的朋友可以了解下,希望能够给你带来帮助...

    鲸落之·海10022022-02-22
  • C/C++C++中事件机制的简洁实现及需要放弃的特性

    C++中事件机制的简洁实现及需要放弃的特性

    事件模型是被广泛使用的好东西,但是C++标准库里没有现成的,现在VC11可以用在XP下了,那么就痛快的拿起C++11提供的先进设施组合出一个轻便的实现吧感兴...

    C++教程网1892020-11-17
  • C/C++json error: Use of overloaded operator [] is ambiguous错误的解决方法

    json error: Use of overloaded operator [] is ambiguous错误的解决方法

    今天小编就为大家分享一篇关于json error: Use of overloaded operator [] is ambiguous错误的解决方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值...

    stpeace8622021-07-27
  • C/C++c语言定时器示例分享

    c语言定时器示例分享

    在linux下开发,使用的是C语言。适用于需要定时的软件开发,以系统真实的时间来计算,它送出SIGALRM信号。每隔一秒定时一次...

    C语言程序设计11642021-01-19
  • C/C++MFC LoadImage用法案例详解

    MFC LoadImage用法案例详解

    这篇文章主要介绍了MFC LoadImage用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...

    HisinWang5502021-12-21
  • C/C++opencv3/C++实现霍夫圆/直线检测

    opencv3/C++实现霍夫圆/直线检测

    今天小编就为大家分享一篇opencv3/C++实现霍夫圆/直线检测,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    阿卡蒂奥7962021-08-08
  • C/C++MFC Frame-Splitter模型实例原理解析

    MFC Frame-Splitter模型实例原理解析

    这篇文章主要介绍了MFC Frame-Splitter模型实例原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以...

    htj1011002021-09-18
  • C/C++C++实现LeetCode(191.位1的个数)

    C++实现LeetCode(191.位1的个数)

    这篇文章主要介绍了C++实现LeetCode(191.位1的个数),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...

    Grandyang10962021-12-13