跳到内容

C++ 编程/代码/标准 C 库/其他

来自维基教科书,开放的书籍,为开放的世界

其他标准 C 函数

[编辑 | 编辑源代码]

本节将介绍几个位于上述细分领域之外的函数,但它们是 C 标准库的一部分。

语法
#include <cstdlib>
void abort( void );

abort() 函数终止当前程序。根据实现的不同,函数的返回值可以指示取消(例如,您使用 signal() 函数捕获了 SIGABRT)或失败的中止。

SIGABRT 是进程在调用 abort libc 函数时向自身发送的信号,该函数在 cstdlib 中定义。SIGABRT 信号可以被捕获,但不能被阻塞;如果信号处理程序返回,则所有打开的流将被关闭并刷新,程序将终止(如果合适,则转储核心)。这意味着 abort 调用永远不会返回。由于这种特性,它通常用于在支持库中发出致命条件的信号,在这些情况下,当前操作无法完成,但主程序可以在退出之前执行清理。如果断言失败,也会使用它。

相关主题
assert - atexit - exit
语法
#include <cassert>
assert( exp );

assert() 宏用于测试错误。如果 exp 评估为零,则 assert() 将信息写入 stderr 并退出程序。如果定义了 NDEBUG 宏,则 assert() 宏将被忽略。

相关主题
abort
语法
#include <cstdlib>
int atexit( void (*func)(void) );

atexit() 函数会导致程序终止时调用 func 指向的函数。您可以多次调用 atexit()(至少 32 次,具体取决于您的编译器),这些函数将按照其建立的相反顺序调用。atexit() 函数成功返回零,失败返回非零值。

相关主题
abort - exit
语法
#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 被传递作为程序的返回值,其中通常零表示成功,非零表示错误。

相关主题
abort - atexit - system
语法
#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 关键字。

注意
setjmp 似乎不在 std 命名空间 中。

相关主题
longjmp
语法
#include <csignal>
void (*signal( int sig, void (*handler)(int)) )(int)

signal() 函数接受两个参数 - 第一个是信号标识符,第二个是指向信号处理程序的函数指针,该处理程序接受一个参数。signal 的返回值是指向先前处理程序的函数指针(如果更改信号处理程序时出错,则为 SIG_ERR)。

默认情况下,大多数引发的信号由处理程序 SIG_DFL(通常会关闭程序的默认信号处理程序)或 SIG_IGN(忽略信号并继续执行程序)处理。

当您指定自定义处理程序并且引发信号时,信号处理程序将恢复为默认值。

虽然信号处理程序被throwcatch取代,但某些系统可能仍然要求您使用这些函数来处理某些重要事件。例如,基于 Unix 的系统上的 SIGTERM 信号表示程序应尽快终止。

注意
Solaris 中的标准信号列表
SIGHUP、SIGINT、SIGQUIT、SIGILL、SIGTRAP、SIGABRT、SIGEMT、SIGFPE、SIGKILL、SIGBUS、SIGSEGV、SIGSYS、SIGPIPE、SIGALRM、SIGTERM、SIGUSR1、SIGUSR2、SIGCHLD、SIGPWR、SIGWINCH、SIGURG、SIGIO、SIGSTOP、SIGTSTP、SIGCONT、SIGTTIN、SIGTTOU、SIGVTALRM、SIGPROF、SIGXCPU、SIGXFSZ、SIGWAITING、SIGLWP、SIGFREEZE、SIGTHAW、SIGCANCEL、SIGLOST

相关主题
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() );
相关主题
rand
(标准 C 时间和日期函数) time
语法
#include <cstdlib>
int system( const char *command );

system() 函数通过将其传递给默认命令解释器来运行给定的命令。

如果命令执行没有错误,返回值通常为零。如果命令为NULL,system() 将测试是否有可用的命令解释器。如果有可用的命令解释器,则将返回非零值,如果没有,则返回零。

相关主题
exit - getenv
语法
#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() 宏用于将可变数量的参数传递给函数。

  1. 首先,您必须调用 va_start(),传递有效的va_list和省略号 ("...") 之前最后一个参数变量的名称。第一个参数可以是任何东西;一种使用方法是将其作为描述正在传递的参数数量的整数。
  2. 接下来,您调用 va_arg(),传递va_list和要返回的参数类型。va_arg() 的返回值是当前参数。
  3. 对 va_arg() 重复调用,以获取您拥有的参数数量。
  4. 最后,必须调用 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
华夏公益教科书