C++ 编程/代码/标准 C 库/其他
本节将介绍几个位于上述细分领域之外的函数,但它们是 C 标准库的一部分。
语法 |
#include <cstdlib>
void abort( void );
|
abort() 函数终止当前程序。根据实现的不同,函数的返回值可以指示取消(例如,您使用 signal() 函数捕获了 SIGABRT)或失败的中止。
SIGABRT 是进程在调用 abort libc 函数时向自身发送的信号,该函数在 cstdlib 中定义。SIGABRT 信号可以被捕获,但不能被阻塞;如果信号处理程序返回,则所有打开的流将被关闭并刷新,程序将终止(如果合适,则转储核心)。这意味着 abort 调用永远不会返回。由于这种特性,它通常用于在支持库中发出致命条件的信号,在这些情况下,当前操作无法完成,但主程序可以在退出之前执行清理。如果断言失败,也会使用它。
语法 |
#include <cassert>
assert( exp );
|
assert() 宏用于测试错误。如果 exp 评估为零,则 assert() 将信息写入 stderr 并退出程序。如果定义了 NDEBUG 宏,则 assert() 宏将被忽略。
- 相关主题
- abort
语法 |
#include <cstdlib>
int atexit( void (*func)(void) );
|
atexit() 函数会导致程序终止时调用 func 指向的函数。您可以多次调用 atexit()(至少 32 次,具体取决于您的编译器),这些函数将按照其建立的相反顺序调用。atexit() 函数成功返回零,失败返回非零值。
语法 |
#include <cstdlib>
void* bsearch( const void *key, const void *base, size_t num, size_t size, int (*compare)(const void *, const void *));
|
bsearch() 函数在一个排序数组中执行搜索,返回指向所查询元素的指针或 NULL。
*key 指向与 *base* 中搜索的项目匹配的对象。该数组包含 num 个元素,每个元素的大小为 size。
compare 函数接受指向数组中对象的两个指针 - 这些指针需要先被转换为正在检查的对象类型。如果第一个参数应该在第二个参数之前,则该函数返回 -1,如果第一个参数在之后,则返回 1,如果对象匹配,则返回 0。
- 相关主题
- qsort
语法 |
#include <cstdlib>
void exit( int exit_code );
|
exit() 函数停止程序。exit_code 被传递作为程序的返回值,其中通常零表示成功,非零表示错误。
语法 |
#include <cstdlib>
char *getenv( const char *name );
|
getenv() 函数返回与 name 关联的环境信息,并且高度依赖于实现。如果 name 的信息不可用,则返回 NULL。
- 相关主题
- system
语法 |
#include <csetjmp>
void longjmp( jmp_buf env, int val );
|
longjmp() 函数的行为就像一个跨函数的 goto
语句:它将执行点移动到 env 中找到的记录,并导致 setjmp() 返回 val。使用 longjmp() 可能会对 setjmp() 调用函数中在初始返回后修改的变量产生一些副作用。
longjmp() 不会调用任何创建对象的析构函数。因此,它已被 C++ 异常系统取代,该系统使用 throw 和 catch 关键字。
- 相关主题
- setjmp
语法 |
#include <cstdlib>
void* qsort( const void *base, size_t num, size_t size, int (*compare)(const void *, const void *));
|
qsort() 函数在一个数组上执行 快速排序。请注意,一些实现可能改为使用更有效的排序算法。
*base 指向要排序的数组。该数组包含 num 个元素,每个元素的大小为 size。
compare 函数接受指向数组中对象的两个指针 - 这些指针需要先被转换为正在检查的对象类型。如果第一个参数应该在第二个参数之前,则该函数返回 -1,如果第一个参数在之后,则返回 1,如果对象匹配,则返回 0。
- 相关主题
- bsearch
语法 |
#include <csignal>
int raise(int)
|
raise() 函数发出参数指定的信号。
如果失败,它将返回一个非零值。
- 相关主题
- signal
语法 |
#include <cstdlib>
int rand( void );
|
rand() 函数返回一个介于零和 RAND_MAX 之间的伪随机整数。一个例子
srand( time(NULL) );
for( i = 0; i < 10; i++ )
printf( "Random number #%d: %d\n", i, rand() );
rand() 函数必须在首次调用之前使用 srand() 函数进行播种 - 否则,它将在程序重新启动时始终返回相同的数字。
- 相关主题
- srand
语法 |
#include <csetjmp>
int setjmp( jmp_buf env );
|
setjmp() 函数将当前执行状态存储在 env 中,并返回 0。执行状态包括有关正在执行的代码的基本信息,以备 longjmp() 函数调用。如果并且当 longjmp 被调用时,setjmp() 将返回 longjmp 提供的参数 - 但是,在第二次返回时,在初始 setjmp() 调用后修改的变量可能具有未定义的值。
缓冲区仅在调用函数返回之前有效,即使它是静态声明的。
由于 setjmp() 不理解构造函数或析构函数,因此它已被 C++ 异常系统取代,该系统使用 throw 和 catch 关键字。
- 相关主题
- longjmp
语法 |
#include <csignal>
void (*signal( int sig, void (*handler)(int)) )(int)
|
signal() 函数接受两个参数 - 第一个是信号标识符,第二个是指向信号处理程序的函数指针,该处理程序接受一个参数。signal 的返回值是指向先前处理程序的函数指针(如果更改信号处理程序时出错,则为 SIG_ERR)。
默认情况下,大多数引发的信号由处理程序 SIG_DFL(通常会关闭程序的默认信号处理程序)或 SIG_IGN(忽略信号并继续执行程序)处理。
当您指定自定义处理程序并且引发信号时,信号处理程序将恢复为默认值。
虽然信号处理程序被throw和catch取代,但某些系统可能仍然要求您使用这些函数来处理某些重要事件。例如,基于 Unix 的系统上的 SIGTERM 信号表示程序应尽快终止。
- 相关主题
- raise
语法 |
#include <cstdlib>
void srand( unsigned seed );
|
srand() 函数用于对 rand() 生成的随机序列进行播种。对于任何给定的种子,rand() 将一次又一次地生成特定的“随机”序列。
srand( time(NULL) );
for( i = 0; i < 10; i++ )
printf( "Random number #%d: %d\n", i, rand() );
语法 |
#include <cstdlib>
int system( const char *command );
|
system() 函数通过将其传递给默认命令解释器来运行给定的命令。
如果命令执行没有错误,返回值通常为零。如果命令为NULL,system() 将测试是否有可用的命令解释器。如果有可用的命令解释器,则将返回非零值,如果没有,则返回零。
语法 |
#include <cstdarg>
type va_arg( va_list argptr, type );
void va_end( va_list argptr );
void va_start( va_list argptr, last_parm );
|
va_arg() 宏用于将可变数量的参数传递给函数。
- 首先,您必须调用 va_start(),传递有效的va_list和省略号 ("...") 之前最后一个参数变量的名称。第一个参数可以是任何东西;一种使用方法是将其作为描述正在传递的参数数量的整数。
- 接下来,您调用 va_arg(),传递va_list和要返回的参数类型。va_arg() 的返回值是当前参数。
- 对 va_arg() 重复调用,以获取您拥有的参数数量。
- 最后,必须调用 va_end() 并传递va_list以进行适当的清理。
int sum( int num, ... ) {
int answer = 0;
va_list argptr;
va_start( argptr, num );
for( ; num > 0; num-- ) {
answer += va_arg( argptr, int );
}
va_end( argptr );
return( answer );
}
int main( void ) {
int answer = sum( 4, 4, 3, 2, 1 );
printf( "The answer is %d\n", answer );
return( 0 );
}
此代码显示 10,即 4+3+2+1。
以下是可变参数函数的另一个示例,它是一个简单的打印函数
void my_printf( char *format, ... ) {
va_list argptr;
va_start( argptr, format );
while( *format != '\0' ) {
// string
if( *format == 's' ) {
char* s = va_arg( argptr, char * );
printf( "Printing a string: %s\n", s );
}
// character
else if( *format == 'c' ) {
char c = (char) va_arg( argptr, int );
printf( "Printing a character: %c\n", c );
break;
}
// integer
else if( *format == 'd' ) {
int d = va_arg( argptr, int );
printf( "Printing an integer: %d\n", d );
}
*format++;
}
va_end( argptr );
}
int main( void ) {
my_printf( "sdc", "This is a string", 29, 'X' );
return( 0 );
}
此代码在运行时显示以下输出
Printing a string: This is a string Printing an integer: 29 Printing a character: X