头文件<cstddef>、<cstdlib>、<cstring>
与C对应版本兼容,在C++程序中经常用到。它们是C头文件<stddef.h>、<stdlib.h>、<string.h>
的较新版本,定义了一些常用的常量、宏、类型和函数
<cstddef>
内的各种定义
标识符 | 意义 |
---|---|
NUll | 指针值,用来表示未定义或无值 |
nullptr_t | C++11其用来取代NULL |
size_t | 一种无正负号的型别,用来表示大小(例如元素个数) |
ptrdiff_t | 一种带有正负号的型别,用来表示指针之间的距离 |
max_align_t | 所有环境之最大齐位所对应的类型 |
offsetof(type, mem) | 表示成员mem在某个struct或者union中的偏移量 |
NULL与nullptr
- 在C++11之前,NULL通常用来表示一个不指向任何对象的pointer。自C++11其以nullptr表示这个语义
- C语言中的NULL通常定义为(void*)0,这在C++中并不正确,NULL必须是个整数类型,否则你将无法将NULL赋予一个pointer。这是因为C++并没有定义从void*到任何类型的自动类型转换操作
- nullptr会被自动转换为各种pointer类型,但是不会被转换为任何整数类型
- 从C++11开始使用nullptr取代NULL
下面我们来看个例子:
void f(int);
void f(void*);
f(0); //调用f(int)
f(NULL); //如果NULL被视为0,那么调用的是f(int),可能与你的预期不符
f(nullptr); //调用f(void*)
效果:
null与std::nullptr_t
- std::nullptr_t是一种基础数据类型,定义于中
- std::nullptr_t定义的变量必须初始化
- nullptr属于一种常量,它是属于std::nullptr_t数据类型的
实例:
void f(int) {
std::cout << "int" << std::endl;
}
void f(void*) {
std::cout << "void*" << std::endl;
}
void f(std::nullptr_t) {
std::cout << "std::nullptr_t" << std::endl;
}
int main()
{
f(0);
f(NULL);
f(nullptr);
//必须初始化
std::nullptr_t t = nullptr;
f(t);
return 0;
}
效果:
<cstdlib>
下图列出了一部分定义,具体请参考https://www.cplusplus.com/reference/cstdlib/
EXIT_SUCCESS、EXIT_FAILURE
- 这两被用来传递给exit()的实参,也可以当做main的返回值
atexit()
atexit()注册的函数,在程序正常退出时会依注册相反次序被一一调用。无论是通过exit()退出或从main()尾部退出,都会如此,不需传递任何参数
exit()、abort()
- exit():会销毁所有static对象、清空所有缓冲区,关闭所有IO通道,然后终止程序,终止前会先调用由atexit()注册的函数。如果atexit()注册的函数抛出异常,就会调用terminate()
- abort():会立刻终止函数,不作任何清理工作
abort
是“意外”终止函数,而不是“意料内的结束”- 如果要“意料内的结束并发出一个错误代码”应调用
std::terminate
- 这两个函数都不会销毁局部对象:因为堆叠辗转(stack unwinding)开展不会被执行起来。如果你希望确保所有局部对象的析构函数被调用,应该运用异常(exception)或正常返回机制,然后从main()退出程序
atof
double atof(const char * str);
- 功能: 将字符串转换为双精度
- 从第一个非空白字符开始,尽可能多地使用有效的字符,并将其解释为数值。最后一个有效字符之后的其余字符串将被忽略,并且对该函数的行为没有影响。
- 如果str中的非空白字符的第一个序列没有形成刚刚定义的有效浮点数,或者由于str为空或仅包含空白字符而没有这样的序列存在,则不执行任何转换,该函数返回0.0。
- 返回值
- 成功后,函数将转换后的浮点数作为double值返回。
- 如果无法执行有效的转换,则该函数将返回零(0.0)
- 如果转换后的值超出a的可表示值范围double
- 更健壮的函数是
strtod
例子
/* atof example: sine calculator */
#include <stdio.h> /* printf, fgets */
#include <stdlib.h> /* atof */
#include <math.h> /* sin */
int main ()
{
double n,m;
double pi=3.1415926535;
char buffer[256];
printf ("Enter degrees: ");
fgets (buffer,256,stdin);
n = atof (buffer);
m = sin (n*pi/180);
printf ("The sine of %f degrees is %f\n" , n, m);
return 0;
}
下图展示了头文件中最重要的表达式:用以设定、拷贝、搬移内存的底层函数,这些函数被应用于character trait