程序清单 7-1 经典c程序 P148
/**
* 程序清单 7-1 经典c程序 P148
*
* zy:
* 注意这个经典的c程序是不完整的,没有返回值,没有声明main的返回类型
* 才会造成这样的情况
* 这是因为直接返回了main中栈和寄存器的内容
*
* 书上说返回码的是随机的,但是我始终得到8
*
*/
main() {
printf("hello!");
//return 0;加了这句返回码就是0,并且与exit(0)是一个意思,这样内核会帮助我们做一些清理工作,比如关闭打开的文件
}
结果:
asd@asd-desktop:~/workspace/test/src$ ./a.out
hello!asd@asd-desktop:~/workspace/test/src$ echo $?
8
程序清单 7-2 终止处理程序实例 P150
/**
* 程序清单 7-2 终止处理程序实例 P150
*
* zy:
* atexit函数,使用这个函数可以注册一些函数,
* 注册的函数在main函数调用return和exit时候调用
* 可以帮助我们处理一些事
*
* 注意注册顺序和调用顺序相反,有点类似于栈
*
*/
#include "apue.h"
#include "error.c"
static void my_exit1(void){
printf("first exit handler\n");
}
static void my_exit2(void){
printf("second exit handler\n");
}
int main() {
if(atexit(my_exit2)!=0){//my_exit2作为一个函数,没有参数的()括号
err_sys("can't register my exit2");
}
if(atexit(my_exit1)!=0){
err_sys("can't register my exit1");
}
if(atexit(my_exit1)!=0){
err_sys("can't register my exit1");
}
printf("main is done\n");
return 0;
}
结果:
main is done
first exit handler
first exit handler
second exit handler
asd@asd-desktop:~/workspace/test/src$
程序清单 7-3 将所有命令行参数回送到标准输出上
/**
* 程序清单 7-3 将所有命令行参数回送到标准输出上 P151
*
* zy:
* 执行一个新的进程的时候,调用exec的进程会可以将命令行参数传递给新程序
*/
#include "apue.h"
#include "error.c"
int main(int argc, char **argv) {
int i;
for(i=0;i<argc;i++){//也可以改为for(i=0;argv[i]!=NULL;i++){ 因为argv[argc]==NULL,这是规定
printf("argv[%d] : %s \n",i, argv[i]);
}
exit(0);
}
结果:
asd@asd-desktop:~/workspace/test/src$ ./a.out 123 321 222 111
argv[0] : ./a.out
argv[1] : 123
argv[2] : 321
argv[3] : 222
argv[4] : 111
asd@asd-desktop:~/workspace/test/src$
程序清单 7-4 进行命令处理的典型框架
这是一段学习使用setjmp和longjmp的框架,不能实际运行,只是讲解用,所以就不抄了
程序清单 7-5 setjmp和longjmp实例
这是一段学习使用setjmp和longjmp的框架,不能实际运行,只是讲解用,所以就不抄了程序清单 7-6 可以实际运行。
程序清单 7-6 longjmp对各类变量的影响
/**
* 程序清单 7-6 longjmp对各类变量的影响 P164
*
* zy:
* 不仅能看到使用longjmp是如何使函数进行了跳转,
* 还能够看出自动变量、全局变量、寄存器变量、静态变量、易失变量的变化
*
* 结论:全局和静态、易失变量不会受到优化的影响。
*/
#include "apue.h"
#include "error.c"
#include <setjmp.h>
static void f1(int,int,int,int);
static void f2(void);
static jmp_buf jmpbuffer;
static int globval;
int main(int argc, char **argv) {
int autoval;
register int regival;
volatile int volaval;//强制访存操作,防止编译器去优化,告诉编译器每次必须去内存中取值,而不是从寄存器或者缓存.
static int statval;
globval=1;
autoval=2;
regival=3;
volaval=4;
statval=5;
if(setjmp(jmpbuffer)!=0){
printf("after longjmp: \n");
printf("globval = %d, autoval=%d,regival = %d ,volaval = %d,statval=%d\n"
,globval,autoval,regival,volaval,statval);
exit(0);
}
globval=95;
autoval=96;
regival=97;
volaval=98;
statval=99;
f1(autoval,regival,volaval,statval);
exit(0);//我们的设计是不可能从这里结束函数的。
}
static void f1(int autoval,int regival,int volaval,int statval){
printf("in f1()\n");
printf("globval = %d, autoval=%d,regival = %d ,volaval = %d,statval=%d\n"
,globval,autoval,regival,volaval,statval);
f2();
}
static void f2(void){
longjmp(jmpbuffer,1);
}
结论:
asd@asd-desktop:~/workspace/test/src$ gcc test.c
asd@asd-desktop:~/workspace/test/src$ ./a.out
in f1()
globval = 95, autoval=96,regival = 97 ,volaval = 98,statval=99
after longjmp:
globval = 95, autoval=96,regival = 97 ,volaval = 98,statval=99
asd@asd-desktop:~/workspace/test/src$ gcc -O test.c
asd@asd-desktop:~/workspace/test/src$ ./a.out
in f1()
globval = 95, autoval=96,regival = 97 ,volaval = 98,statval=99
after longjmp:
globval = 95, autoval=2,regival = 3 ,volaval = 98,statval=99
asd@asd-desktop:~/workspace/test/src$
程序清单 7-7 自动变量的不正确使用
/**
* 程序清单 7-7 自动变量的不正确使用 P164
*
* zy:
* 这是一种错误的使用方式,就是不能这么用,因为
* 声明自动变量的函数已经返回后,不能引用这个自动变量了
*
* 正确的方式:使用全局存储的静态变量或者是动态地为其分配空间
*/
#include <stdio.h>
#define DATAFILE "datafile"
FILE *open_data(void){
FILE *fp;
char databuf[BUFSIZ];
if((fp=fopen(DATAFILE,"r"))==NULL)
return NULL;
if(setvbuf(fp,databuf,_IOLBF,BUFSIZ)!=0)
return NULL;
return fp;//这句是错误的,因为其是自动变量
}
程序清单 7-8 打印当前资源限制 P166
/**
* 程序清单 7-8 打印当前资源限制 P166
*
* zy:
* 下面的程序打印了系统所支持的资源的软限制和硬限制,
* 代码中,我们包含了各个资源的名字
* 而各个资源的含义请查看书籍165
*/
#include "apue.h"
#include "error.c"
#if defined (BSE)||defined (MACOS)
#include "sys/time.h"
#define FMT "%10lld"
#else
#define FMT "%10ld"
#endif
#include <sys/resource.h>
#define doit(name) pr_limits(#name,name)
static void pr_limits(char *,int);
int main(int argc, char **argv) {
#ifdef RLIMIT_AS
doit(RLIMIT_AS);
#endif
doit(RLIMIT_CORE);
doit(RLIMIT_CPU);
doit(RLIMIT_DATA);
doit(RLIMIT_FSIZE);
#ifdef RLIMIT_LOCKS
doit(RLIMIT_LOCKS);
#endif
#ifdef RLIMIT_MEMLOCK
doit(RLIMIT_MEMLOCK);
#endif
doit(RLIMIT_NOFILE);
#ifdef RLIMIT_NPROC
doit(RLIMIT_NPROC);
#endif
#ifdef RLIMIT_RSS
doit(RLIMIT_RSS);
#endif
#ifdef RLIMIT_SBSIZE
doit(RLIMIT_SBSIZE);
#endif
doit(RLIMIT_STACK);
#ifdef RLIMIT_VMEM
doit(RLIMIT_VMEM);
#endif
exit(0);
}
static void pr_limits(char *name ,int resource){
struct rlimit limit;
if(getrlimit(resource,&limit)<0){
err_sys("getrlimit error for %s",name);
}
printf("%-14s",name);
if(limit.rlim_cur==RLIM_INFINITY){
printf("(infinite)");
}else {
printf(FMT,limit.rlim_cur);
}
if(limit.rlim_max==RLIM_INFINITY){
printf("(infinite)");
}else {
printf(FMT,limit.rlim_max);
}
putchar((int)'\n');
}
结果:
asd@asd-desktop:~/workspace/test/src$ ./a.out
RLIMIT_AS (infinite)(infinite)
RLIMIT_CORE 0(infinite)
RLIMIT_CPU (infinite)(infinite)
RLIMIT_DATA (infinite)(infinite)
RLIMIT_FSIZE (infinite)(infinite)
RLIMIT_LOCKS (infinite)(infinite)
RLIMIT_MEMLOCK 65536 65536
RLIMIT_NOFILE 1024 4096
RLIMIT_NPROC 15970 15970
RLIMIT_RSS (infinite)(infinite)
RLIMIT_STACK 8388608(infinite)
asd@asd-desktop:~/workspace/test/src$