C缺陷与陷阱

最近阅读C缺陷与陷阱,发现很多有意思的地方,在此作为记录.

No 1. 某些编译器允许嵌套注释。请写一个测试程序,要求:无论是对允许嵌套注释的编译器还是对不允许嵌套注释的编译器,改程序都能正常通过编译,但两种情况下程序执行的结果却不相同.

答案:

#include <stdio.h>

int main()

{

int i=/*/*/0*/**/1;

printf("%d\n",i);

}

这个解法主要利用了编译器作词法分析时的“贪心法”规则。如果编译器允许嵌套注释,则上式将被解释为:1

如果不允许嵌套注释,上面的表达式因此将被这样解释:0......

C语言中宏的用法

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

宏基础

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

标示符别名

#define BUFFER_SIZE 1024

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

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

#define NUMBERS 1, \

2, \

3

预处理阶段int x[] = { N......

关于 Markdown

基本语法标题

# 一级标题

## 二级标题

### 三级标题

#### 四级标题

##### 五级标题

###### 六级标题

分别对应HTML中的<h1>一级标题</h1>,以此类推。

用两个星号标记起来,表示加粗,*一个星号,表示斜体*,这样子表示删除,这些就是最基本的语法了。

插入链接

插入链接:

这是一个 [链接](http://url.com/)

快速链接:

只需要在网址头尾用尖括号包裹即可,比如<http://url.com>

特别支持:

[Google (target=_blank id=google_......

内存对齐

忙里偷闲在看《征服C指针》这本书,虽然这本书写的比较基础可以是还是从中发现了一些有意思的地方,不过当看到内存对齐这块时却产生了如下疑问.

typedef struct
{
    int int1;
    double double1;
    char char1;
    double double2;
}Hoge;

那么问题来了,sizeof(Hoge)为多少?

作者交代了,在其环境中sizeof(int)为4,sizeof(double)为8,sizeof(char)为1.

字节排序

在所有的介绍字节序的文章中都会提到字节序分为两类:Big-Endian和Little-Endian,引用标准的Big-Endian和Little-Endian的定义如下:

a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

c) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。

/*

Name: 字节排序

Copyright: 52coder.net

Author: 52c......

编程练习

描述

编写这样一个程序:

接收来自标准输入的n条指令,指令有如下三种:

a 后面跟一个整数,表示向集合插入一个数

d 后面跟一个整数,表示从集合删除一个数,集合中有多个指定数时,删除一个即可

p 从小到大打印出集合中的数

输入

每行输入一条指令,注意指令可能不符合规范,整数可能超出C语言长整形范围,可能带符号,但长度不会超过100

输出

当输入指令为p时,从小到大输出集合中的数,当指令不合法时,输出“Invalid Command”

输入样例

a -2

a 31415926535897932

c

a 1

a 4

a 4

d......