第一章:快速上手
1.1 简介
comment
/*
** this is a comment.
**
*/
/* this is a commit. */
#if 0
statements
#endif
stdlib.h 定义了EXIT_SUCCESS EXIT_FAILURE
C函数传递规则:所有传递给函数的参数都是按值传递的。
软件开销的最大之处并非编写,而是维护。
` "Hello"在内存中占据6个字节空间,H e l l o 和 NUL.
常用 scanf 格式码 %d, %ld, %f, %lf, %c, %s
常用 printf格式码 %d, %o, %x, %g, %c, %s
警告:机械地把printf的函数格式码照搬于scanf函数。
第二章:基本概念
2.1 环境
执行:运行时堆栈stack 用于存储函数的局部变量和返回地址;静态内存,存储全局变量和静态变量
2.3 程序风格
不良的风格和不良的文档是软件生产和维护代价高昂的两个重要原因。
1. 空行用于分隔不同的逻辑代码段
2. if 在括号和表达式之间留下一个空格
3. 在绝大多数操作符的使用中,中间都隔以空格,复杂的表达式,省略空格。
4. TAB键用于缩进。
5. 函数定义,,返回类型出现于独立的一行,函数名字在下一行的起始处。
第三章:数据
变量的三个属性--作用域,链接属性和存储属性
3.1 基本数据
C 4种数据类型--整型,浮点,指针和聚合类型(数组,结构)
ANSI标准给出了各种整型值的最小允许范围。
limit.h 说明了各种不同的整型类型的特点。
缺省的char要么是unsigned char, 要么是signed char, 这取决于编译器。
unsigned int const i = 10;
123L long int
十进制整形字面值可能是int, long, 或unsigned long, 缺省情况下,它是最短类型但能完全容纳这个值。
八进制和十六进制字面值可能的类型是int, unsigned int, long或者unsigned long.
另外,字符常量,他们的类型总是int.
float.h 定义了FLT_MAX, DBL_MAX LDBL_MAX, FLT_MIN, DBL_MIN, LDBL_MIN.
浮点数字面值在缺省情况下都是double类型的。
3.1415F浮点型
字符串 如果你需要修改字符串,请把它储存于数组中。
你不能把字符串常量赋值给一个字符数组,因为字符串常量的直接值是一个指针而不是这些字符本身。
如果下标值是从那些已知是正确的值计算得来,那无需检查他的值,否则在使用前必须进行检查,确保在有效的范围内。
3.2 声明
int *b, c, d; b指针,c, d 整型
int *b, *c, *d;
char *message = "hello world!";
typedef char *ptr_to_char; ptr_to_char a;
typedef 在结构中特别有用
int const *pci; 指向整型常量的指针
int * const cpi; 指向整型的常量指针
int const * const cpci;
#define 创建名字常量
3.5 作用域
4种不同的作用域--文件作用域, 函数作用域, 代码作用域, 原型作用域
代码块作用域--任何在代码块的开始位置声明的标识符都具有代码块作用域。
你应该避免在嵌套的代码块中出现相同的变量,我们并没有的理由使用这种技巧。
文件作用域--任何在所有代码块之外声明的标识符都具有文件作用域
3.6 链接属性
3种 external, internal, none
关键字extern, static 修改标识符的链接属性。
static int b;
extern int c(int d);
3.7 储存类型
存储变量:普通内存,运行时堆栈,硬件寄存器
静态变量 --静态内存
自动变量 --运行时堆栈
寄存器变量-寄存器
在典型情况下,你希望把那些使用频率最高的那些变量声明为寄存器变量,尤其是那些频繁执行间接访问操作的指针。
静态变量初始化为0,自动变量初始值为垃圾。
第四章:语句
C 并不存在专门的赋值语句,而是统一用“表达式语句”代替。
4.1 空语句
;
4.2 表达式语句
赋值就是一种操作,就像加减法一样,所以赋值就在表达式中进行。
x = y + 3;
完全合法:
y + 3;
getchar();
副作用
for 循环有一种风格上的优势
在每个switch 语句中都放一个default 子句是一个好习惯,可以检测到任何非法值,除非。
第五章:操作符和表达式
5.1 操作符
<< 左移位是逻辑移位
>> 右移位,一种是逻辑移位(补0),一种是算术移位(补最高位)
警告:标准说明无符号值执行的所有移位都是逻辑移位,但对于有符号值,取决于编译器。
a << -5 标准说明这类移位的行为是未定义的。
赋值:= 赋值操作符,赋值是表达式中的一种,而不是某种类型的语句。
ch = getchar() != EOF getchar返回int型,ch不能是char类型。
你应该尽量使用复合赋值符。
单目操作符:!++ -- ~ - + & * sizeof (类型)
!操作符的优先级很高,所以如果表达式中含了其他操作符,你最好把表达式放在一对括号里。
逻辑操作符: ”短路求值“
表达式求值:
隐式类型转换:C语言的整型算术运算至少一缺省整型的精度进行运算的。所以字符型和短整型在使用之前被转换为普通整型,
叫做整型提升
char a, b, c;
a = b + c; b c 的值被提升为普通整型,然后执行加法运算,加法运算的结果将被截断,然后存于a中。
算术转换:如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另外一个操作数的类型,否则操作
就无法进行。
long double, double, float, unsigned long int, long int, unsigned int, int
int a = 5000;
int b = 25;
long c = a*b; 在16位整数的机器上,这个乘法就会溢出。
改为 long c = (long) a*b;
1.1 简介
comment
/*
** this is a comment.
**
*/
/* this is a commit. */
#if 0
statements
#endif
stdlib.h 定义了EXIT_SUCCESS EXIT_FAILURE
C函数传递规则:所有传递给函数的参数都是按值传递的。
软件开销的最大之处并非编写,而是维护。
` "Hello"在内存中占据6个字节空间,H e l l o 和 NUL.
常用 scanf 格式码 %d, %ld, %f, %lf, %c, %s
常用 printf格式码 %d, %o, %x, %g, %c, %s
警告:机械地把printf的函数格式码照搬于scanf函数。
第二章:基本概念
2.1 环境
执行:运行时堆栈stack 用于存储函数的局部变量和返回地址;静态内存,存储全局变量和静态变量
2.3 程序风格
不良的风格和不良的文档是软件生产和维护代价高昂的两个重要原因。
1. 空行用于分隔不同的逻辑代码段
2. if 在括号和表达式之间留下一个空格
3. 在绝大多数操作符的使用中,中间都隔以空格,复杂的表达式,省略空格。
4. TAB键用于缩进。
5. 函数定义,,返回类型出现于独立的一行,函数名字在下一行的起始处。
第三章:数据
变量的三个属性--作用域,链接属性和存储属性
3.1 基本数据
C 4种数据类型--整型,浮点,指针和聚合类型(数组,结构)
ANSI标准给出了各种整型值的最小允许范围。
limit.h 说明了各种不同的整型类型的特点。
缺省的char要么是unsigned char, 要么是signed char, 这取决于编译器。
unsigned int const i = 10;
123L long int
十进制整形字面值可能是int, long, 或unsigned long, 缺省情况下,它是最短类型但能完全容纳这个值。
八进制和十六进制字面值可能的类型是int, unsigned int, long或者unsigned long.
另外,字符常量,他们的类型总是int.
float.h 定义了FLT_MAX, DBL_MAX LDBL_MAX, FLT_MIN, DBL_MIN, LDBL_MIN.
浮点数字面值在缺省情况下都是double类型的。
3.1415F浮点型
字符串 如果你需要修改字符串,请把它储存于数组中。
你不能把字符串常量赋值给一个字符数组,因为字符串常量的直接值是一个指针而不是这些字符本身。
如果下标值是从那些已知是正确的值计算得来,那无需检查他的值,否则在使用前必须进行检查,确保在有效的范围内。
3.2 声明
int *b, c, d; b指针,c, d 整型
int *b, *c, *d;
char *message = "hello world!";
typedef char *ptr_to_char; ptr_to_char a;
typedef 在结构中特别有用
int const *pci; 指向整型常量的指针
int * const cpi; 指向整型的常量指针
int const * const cpci;
#define 创建名字常量
3.5 作用域
4种不同的作用域--文件作用域, 函数作用域, 代码作用域, 原型作用域
代码块作用域--任何在代码块的开始位置声明的标识符都具有代码块作用域。
你应该避免在嵌套的代码块中出现相同的变量,我们并没有的理由使用这种技巧。
文件作用域--任何在所有代码块之外声明的标识符都具有文件作用域
3.6 链接属性
3种 external, internal, none
关键字extern, static 修改标识符的链接属性。
static int b;
extern int c(int d);
3.7 储存类型
存储变量:普通内存,运行时堆栈,硬件寄存器
静态变量 --静态内存
自动变量 --运行时堆栈
寄存器变量-寄存器
在典型情况下,你希望把那些使用频率最高的那些变量声明为寄存器变量,尤其是那些频繁执行间接访问操作的指针。
静态变量初始化为0,自动变量初始值为垃圾。
第四章:语句
C 并不存在专门的赋值语句,而是统一用“表达式语句”代替。
4.1 空语句
;
4.2 表达式语句
赋值就是一种操作,就像加减法一样,所以赋值就在表达式中进行。
x = y + 3;
完全合法:
y + 3;
getchar();
副作用
for 循环有一种风格上的优势
在每个switch 语句中都放一个default 子句是一个好习惯,可以检测到任何非法值,除非。
第五章:操作符和表达式
5.1 操作符
<< 左移位是逻辑移位
>> 右移位,一种是逻辑移位(补0),一种是算术移位(补最高位)
警告:标准说明无符号值执行的所有移位都是逻辑移位,但对于有符号值,取决于编译器。
a << -5 标准说明这类移位的行为是未定义的。
赋值:= 赋值操作符,赋值是表达式中的一种,而不是某种类型的语句。
ch = getchar() != EOF getchar返回int型,ch不能是char类型。
你应该尽量使用复合赋值符。
单目操作符:!++ -- ~ - + & * sizeof (类型)
!操作符的优先级很高,所以如果表达式中含了其他操作符,你最好把表达式放在一对括号里。
逻辑操作符: ”短路求值“
表达式求值:
隐式类型转换:C语言的整型算术运算至少一缺省整型的精度进行运算的。所以字符型和短整型在使用之前被转换为普通整型,
叫做整型提升
char a, b, c;
a = b + c; b c 的值被提升为普通整型,然后执行加法运算,加法运算的结果将被截断,然后存于a中。
算术转换:如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另外一个操作数的类型,否则操作
就无法进行。
long double, double, float, unsigned long int, long int, unsigned int, int
int a = 5000;
int b = 25;
long c = a*b; 在16位整数的机器上,这个乘法就会溢出。
改为 long c = (long) a*b;