下面介绍了其他一下c语言其他一点用的比较少的东西,和一些比较容易错误的地方,还是一样的办法,将问题以注释的形式写在了代码之中,主要是在学习时,边看边亲自动手试了一下,而整理成条款的话比较枯燥乏味,所以直接以代码加注释的形式贴出,如下:
#include <stdio.h>
//用于捕捉异步事件
#include <signal.h>
//double square();
/*
1 宏定义需要注意空格
#define f (x) ((x)-1)
被解释为 f (x)((x)-1)
因为f和(x)之间有一个空格
2 还有宏不是函数
#define abs(x) (((x)>=0)?(x):-(x))
abs(a-b)会被解释为
a-b>0?a-b:-a-b
其中-a-b相当于(-a)-b
3 宏并不是语句
#define assert(e) if(!e) assert_error(_FILE_,_LINE_)
//其中_FILE_和_LINE_是内建与c语言预处理器中的宏,它们会被扩展为
//所在文件的文件名和所处代码行的行号
if(x>0 && y>0)
assert(x>y)
else
assert(y>x)会被解释为
if(x>0 && y>0)
if(!(x>y)) assert_error(_FILE_,_LINE_);
else
if(!(y>x)) assert_error(_FILE_,_LINE_);
4 宏并不是类型定义
#define FOOTYPE struct foo
//foo是自定义的结构体类型
FOOTYPE a;
FOOTYPE b,c;
上面的使用正确,但是不代表FOOTYPE是一种类型
*/
//使用errno检测错误
main()
{
// register
// int c;
/*
使用缓冲区,这里暂时不确定怎么使用,但是知道其原理是
比较重要的,还有c语言提供了该种功能
*/
// static char buf[BUFSIZ];
// setbuf(stdout,buf);
while((c = getchar()) != EOF)
putchar(c);
/*
单独的下面这段程序不能执行成功,vc 6.0的环境
NULL表示为指向内存为0的位置,但在禁止读取内存
地址为0的机器上,该程序不能执行成功,很显然,
我的电脑没有执行成功。
char *p;
p= NULL;
printf("Location 0 contains %d\n",*p);
*/
/*
求余的运算应尽量避免出现负数的情况,结果可能
会和想象中差别很大
*/
// int x=10.0;
// printf("%g",square(x));
}
/*
//该种写法暂时不能通过编译,可能是老版本的c语言的用法
double
square(x)
double x;
{
return x*x;
}
*/
补一段代码:
c语言多参数示例,下面函数的功能是对多个参数求和,利用的是c语言参数自右向左压栈传递的方式,*p是取num后面的第一个参数
int __cdecl Sum(int num, ...)
{
int *p = &num + 1;
int ret = 0;
while(num --)
{
ret += *p++;
}
return ret;
}
下面的代码纯粹是觉得比有趣
#include <stdio.h>
#include <setjmp.h>
jmp_buf b;
void Func()
{
longjmp(b ,1);
}
int main()
{
if(setjmp(b))
{
cout << " World\n";
}
else
{
cout <<"hello ";
Func();
}
system("pause");
}
上面的代码输出结果是 hello world 。是不是很不按常理,实际上,当setjump返回时,会返回0,此时会打印hello,但是func中的longjmp的作用 ,就是然程序的执行流程回到当初的setjump返回的时刻,并且返回longjump指定返回的值(longjmp的参数2),也就是1,所以此时会打出world并退出。很神奇吧,只是当增长见识用,实际工作编程代码,不建议使用这个难以理解的逻辑行为。