apue《UNIX环境高级编程第三版》第二章答案详解

来源:互联网 发布:安徽工程大学网络教学 编辑:程序博客网 时间:2024/04/30 15:41

转载请注明本博客地址:http://blog.csdn.net/hubbybob1/article/details/46982215

UNIX高级编程第二章习题答案:

2.1在2.8节中基本数据类型可以在多个文件中定义。例如,在FreeBSD 8.0中,size_t在29个不同的文件中都有定义,由于一个程序可能包含这29个不同的头文件,在ISO C 却不允许对同一个名字进行多次typedef,那么如何编写这些头文件呢?

     :这个问题可以通过一段小代码来验证,先编写2-1.c代码如下,那么调换头文件的顺序会造成什么样的结果呢?

<span style="font-size:18px;"><span style="font-size:18px;">#include <stdio.h>  #include <unistd.h>  #include <stdlib.h> #include "2-1-2.h"//把这两个.<span style="font-family:宋体;">h文件调换已下会出现什么样的结果呢</span>#include "2-1-1.h"#define  i 8 int main(){    printf("%d  ",i);//<span style="font-family:宋体;">这个地方打印的结果是什么</span>,你可以试一试?????   printf("\n");   return 0;}</span></span>

下面可以编写两个.h文件,如下:

<span style="font-size:18px;">//2-1-1.h#include <stdio.h>#include <unistd.h>#include <stdlib.h>#ifndef i  //采用的识#ifdef或者#ifndef的模式#define  i  0#endif//2-1-2.h#include <stdio.h>#include <unistd.h>#include <stdlib.h>#ifndef i#define  i 5#endif</span>
这样设置一个检测的开开关,就可以解决多头文件重复typedef的问题了,如下:
<span style="font-size:18px;">#ifndef _MACHINE_TYPES_H_#define _MACHINE_TYPES_H_typedef int _int32_t;typedef unsigned int _uint32_t;.........typedef _uint32_t _size_t;.........#enddef</span>
这样就可以避免重复定义了。

2.2检测系统的头文件。列出实现基本系统数据类型所用到的实际类型。

        答:我所使用的系统为Ubuntu版本的Linux系统,而Linux内核的头文件放在/usr/include/linux/和/usr/include/sys/两个目录下,在我么编写程序的时候总会添加一个头文件那就是:

#include<sys/types.h>
那么我们就去看看这个头文件到底做了什么,在/usr/include/sys目录下,如下所示:
<span style="font-size:18px;">#ifndef _SYS_TYPES_H#define _SYS_TYPES_H  1 #include <features.h> __BEGIN_DECLS#include <bits/types.h>  #ifdef  __USE_BSD# ifndef __u_char_definedtypedef __u_char u_char;typedef __u_short u_short;typedef __u_int u_int;typedef __u_long u_long;typedef __quad_t quad_t;typedef __u_quad_t u_quad_t;typedef __fsid_t fsid_t;# define __u_char_defined# endif#endif。。。 </span>
但是这里面依然找不到,拿就要找他的头文件了:
<span style="font-size:18px;"><span style="font-size:18px;"><pre name="code" class="cpp">#include <features.h>//在目录 /usr/include 下用来定义和取消一些开关所用的,自己去查看</span></span>
#include <bits/types.h>//在目录 /usr/include/bits 下
那么就来看看bits下的types.h文件吧。如下:                                                                                                                                                   
<span style="font-size:18px;"><pre name="code" class="cpp">#include <features.h>#include <bits/wordsize.h>  /* Convenience types.  */typedef unsigned char __u_char;typedef unsigned short int __u_short;typedef unsigned int __u_int;typedef unsigned long int __u_long;  /* Fixed-size types, underlying types depend on word size and compiler.  */typedef signed char __int8_t;typedef unsigned char __uint8_t;typedef signed short int __int16_t;typedef unsigned short int __uint16_t;typedef signed int __int32_t;typedef unsigned int __uint32_t;#if __WORDSIZE == 64typedef signed long int __int64_t;typedef unsigned long int __uint64_t;#elif defined __GLIBC_HAVE_LONG_LONG __extension__ typedef signed long long int __int64_t;__extension__ typedef unsigned long long int __uint64_t;#endif。。。  #define __S16_TYPE    short int#define __U16_TYPE    unsigned short int#define __S32_TYPE    int#define __U32_TYPE    unsigned int#define __SLONGWORD_TYPE  long int#define __ULONGWORD_TYPE  unsigned long int#if __WORDSIZE == 32#define __SQUAD_TYPE   __quad_t#define __UQUAD_TYPE   __u_quad_t#define __SWORD_TYPE   int#define __UWORD_TYPE   unsigned int#define __SLONG32_TYPE   long int#define __ULONG32_TYPE   unsigned long int。。。</span>

2.3改写图2-17中的程序,使其在sysconf为OPEN_MAX限制返回LONG_MAX时,避免进行不必要的处理。

    答:尽然要修改程序,那就要先看看源程序的到底实现了什么,源码如下所示:

<span style="font-size:18px;">#include <stdio.h>                                                                                                                                   #include <limits.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#ifdef OPEN_MAXstatic long openmax = OPEN_MAX;//OPEN_MAX每个进程最大打开文件数,linux为1024#elsestatic long openmax = 0;#endif/* If OPEN_MAX is indeterminate ,no gurante this is adequate */#define OPEN_MAX_GUESS 256long open_max(void){//其实if内的程序没有执行因为已经定义了OPEN_MAX,           if(openmax == 0){errno = 0;if((openmax = sysconf(_SC_OPEN_MAX)) < 0)//_SC_OPEN_MAX:每个进程最大打开文件数 {printf("1.openmax= %ld\n",openmax);if(errno == 0)openmax = OPEN_MAX_GUESS; /*it's indeterminate*/elseprintf("sysconf error for _SC_OPEN_MAX"); }}printf("2.openmax= %ld\n",openmax);  return(openmax);}int main(){  open_max();  return 0;}//编译 gcc -o 2-17 2-17.c 然后运行</span>

有三种情况:

1,一开时OPEN_MAX是被定义过的,有值linux下为1024,此openmax一开始就被初始化为1024,这一样就直接运行第三个printf

2,假设初始化openmax为0,那结果会使怎样的呢,同样只会执行第三个printf,打印的结果没有变化,因为通过sysconf获取linux的OPEN_MAX的值为1024,下面的if不成立,

<span style="font-size:18px;">if((openmax = sysconf(_SC_OPEN_MAX)) < 0)//_SC_OPEN_MAX:每个进程最大打开文件数</span>

那么就执行第三个printf

3,假设openmax被初始话为0,而通过sysconf函数获取的值小于0成立,那么就会执行地一个printf

<span style="font-size:18px;">printf("1.openmax= %ld\n",openmax);</span>
此时就会查看errno的值,来确定是否为sysconf erro,那么问题来了当sysconf返回的值限制值LONG_MAX时,怎么处理呢,这就是本题的答案,代码如下所示:

#include <stdio.h>#include <limits.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <sys/resource.h>//rlimit的相关库,要不然会报未定义错误#define OPEN_MAX_GUESS 256long open_max(void){   long openmax;   struct rlimit rl;   if((openmax = sysconf(_SC_OPEN_MAX)) < 0 || openmax == LONG_MAX)//_SC_OPEN_MAX:每个进程最大打开文件数     {   if(getrlimit(RLIMIT_NOFILE,&rl) < 0)//获取每个进程最大打开文件描述符数  printf("1.can't get file limit ");       if(rl.rlim_max == RLIM_INFINITY)  openmax = OPEN_MAX_GUESS;       elseopenmax = rl.rlim_max;      } printf("2.openmax == %ld \n",openmax);}int main(){  open_max();  return 0;}
如果OPEN_MAX未确定或者大的出奇(即等于LONG_MAX),那么可用getrlimit得到每个进程的最大打开文件描述符数。运行的结果如下:



1 0
原创粉丝点击