APUE读书笔记-第一章Unix基础知识

在kindle奢侈的花了90大洋买了APUE UNIX环境高级编程这本书,未来的日子里要计划读完此本书,鉴于之前读书没有做笔记,所以从这本800页大块头开始,每周更新读书笔记.

C缺陷与陷阱

最近阅读C缺陷与陷阱,发现很多有意思的地方,在此作为记录.
No 1. 某些编译器允许嵌套注释。请写一个测试程序,要求:无论是对允许嵌套注释的编译器还是对不允许嵌套注释的编译器,改程序都能正常通过编译,但两种情况下程序执行的结果却不相同.
答案:

#include <stdio.h>
int main()
{
    int i=/*/*/0*/**/1;
    printf("%d\n",i);
    return 0;
}

这个解法主要利用了编译器作词法分析时的“大嘴法”规则。如果编译器允许嵌套注释,则上式将被解释为:1
如果不允许嵌套注释,上面的表达式因此将被这样解释:0*1也就是0。

细说指针

因为在工作中踩到了指针相关的坑,所以在这里记录下来问题产生的原因,以免再次遇到同样的错误。如果你对文章中的观点、内容存在不一样的看法,欢迎通过关于博主页面中的Email与我联系。

需求:
将代码提取成函数,代码如下:

    mr_cfg_bsc_info_t   *mir_list = NULL;
    mir_list在主函数中是一级指针的形式,我提取函数时接口用了二级指针如下格式:
    int32_t mirror_suspend_flag_abnormal_handle(mr_cfg_bsc_info_t *mir_info,lun_info_t *lun_info,uint32_t mir_num,mr_cfg_bsc_info_t **mir_list)
复制原有的代码:
    found_rmt_cfg = FALSE;
    for (rmt_cfg_idx = 0; rmt_cfg_idx < mir_num; rmt_cfg_idx++)
    {
        rmt_cfg = &mir_list[rmt_cfg_idx];
        if(0 == memcmp(&mir_info->remote_uuid, &rmt_cfg->local_uuid, sizeof(uuid_t)))
        {
            found_rmt_cfg = TRUE;
            break;
        }
    }
将rmt_cfg = &mir_list[rmt_cfg_idx];修改成rmt_cfg = mir_list[rmt_cfg_idx];
我自以为自己简化了代码,使函数主题看起来更清晰,却哪知道埋下了一个定时炸弹.

工作备忘录

HWManager -t -oppwrctl -pwron 对端开机
HWManager -t -oppwrctl -foff 对端关机
HWManager -t -host -rst 本端开机
HWManager -t -host -foff 本端关机

问题单提交规范:
【问题描述】
【操作步骤】
【预期结果】
【实际结果】

柔性数组

#include <stdio.h>
#include <malloc.h>
typedef struct _soft_array
{
    int len;
    int array[];//int array[0];两种形式 
}SoftArray;

int main()
{  
    int i = 0;
    SoftArray* sa = (SoftArray*)malloc(sizeof(SoftArray) + sizeof(int) * 10);

    sa->len = 10;

    for(i=0; i<sa->len; i++)
    {
        sa->array[i] = i + 1;
    }

    for(i=0; i<sa->len; i++)
    {
        printf("%d\n", sa->array[i]);   
    }

    free(sa);

    return 0;
}

柔性数组是C99的扩展,简而言之就是一个在struct结构里的标识占位符(不占结构struct的空间)。

C经典程序集锦

集锦一:

#include <stdio.h>

int array[]={23,34,12,17,204,99,16};

#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))

int main()

{

int d=-1;

int x;

if(d <= TOTAL_ELEMENTS-2)

printf("Hello World.\n");

system("pause");

return 0;

}

TOTAL_ELEMENTS所定义的值是unsigned int 类型......

C语言中宏的用法与技巧

总结一下C语言中宏的一些特殊用法和几个容易出错的地方。由于本文主要参考GCC文档,某些细节在别的编译器可能有细微差别。

宏基础

宏仅仅是在C预处理阶段的一种文本替换工具,编译完之后对二进制代码不可见。基本用法如下:

  1. 标示符别名
#define BUFFER_SIZE 1024

预处理阶段,foo = (char *) malloc (BUFFER_SIZE);会被替换成foo = (char *) malloc (1024);

宏体换行需要在行末加反斜杠\

编程练习

描述
编写这样一个程序:
接收来自标准输入的n条指令,指令有如下三种:

  1. a 后面跟一个整数,表示向集合插入一个数
  2. d 后面跟一个整数,表示从集合删除一个数,集合中有多个指定数时,删除一个即可
  3. p 从小到大打印出集合中的数 输入 每行输入一条指令,注意指令可能不符合规范,整数可能超出C语言长整形范围,可能带符号,但长度不会超过100 输出 当输入指令为p时,从小到大输出集合中的数,当指令不合法时,输出“Invalid Command” 输入样例 a -2 a 31415926535897932 c a 1 a 4 a 4 d 4 p