预处理
主要指示编译器在编译之前完成预处理。 预处理指令不是C++语句,所以#xxxx 之后不需要加 ; 结尾
常见预处理包括**#include 、#define 、#if 、 #else 、 #line **
define
用于创建符号常量、通常称为宏。
#define PI 3.14159
参数宏
#define MIN(a,b) (a<b ? a : b)
条件编译
#ifdef xxx
xxxxx
#endif
也可以用#if 0来写注释:
#if 0
注释内容
#endif
运算符#和##
#define f(x) #x
假设我们
cout<<f(x);
预处理器会将f(x)转换成“x”
C++预定义宏
预定义的宏有
- LINE ,代表行号
- FILE,代表文件名
- DATE,代表月 日 年的字符串
- TIME,代表时:分:秒 的字符串
信号处理
信号是由操作系统传给进程的中断,会提早终止一个程序。 在一般操作系统上,按Ctrl+c会产生中断。
有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 中
signal()
C++ 信号处理库提供了 signal 函数,用来捕获突发事件。以下是 signal() 函数的语法:
void (*signal(int signum,void(fun*)(int))) (int)
这个函数接收两个参数:第一个参数是一个整数,代表了信号的编号;第二个参数是一个指向信号处理函数的指针。
使用 signal() 函数捕获 SIGINT 信号。不管您想在程序中捕获什么信号,您都必须使用 signal 函数来注册信号,并将其与信号处理程序相关联。看看下面的实例:
#include <iostream>
#include <csignal>
#include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
exit(signum);
}
int main ()
{
signal(SIGINT, signalHandler);
while(1){
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}
我们注册信号SIGINT,发生中断时,跳转到函数signalhander处理问题。 正常运行就一直输出字符串,当我们按ctrl+c中断这个函数时,就会看见程序捕获了信号,并打印内容输出:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.
raise()
可以使用函数 raise() 生成信号,该函数带有一个整数信号编号作为参数,语法如下:
int raise (signal sig);
sig 是要发送的信号的编号,这些信号包括:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP。
以下是我们使用 raise() 函数内部生成信号的实例: 用rasise生成一个SIGINT信号,进而signal跳转到处理函数。
#include <iostream>
#include <csignal>
#include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
exit(signum);
}
int main ()
{
int i = 0;
signal(SIGINT, signalHandler);
while(++i){
cout << "Going to sleep...." << endl;
if( i == 3 ){
raise( SIGINT);
}
sleep(1);
}
return 0;
}
|