目录

一  写在前面

1.1 书籍信息

1.2 简单叙述

二   类型、运算符与表达式

2.1 变量名

2.2 数据类型及长度

2.3 常量

2.4 声明

2.5 算数运算符

2.6 关系运算符与逻辑运算符

2.7 类型转换

2.8 自增运算符与自减运算符

2.9 按位运算符

2.10 赋值运算符与表达式

2.11 条件表达式

2.12 运算符优先级与求值次序

三  流控制

3.1 语句与程序块

3.2 if-else

3.3 else if 语句

3.4 switch语句

3.5 while与for循环语句

3.6 do-while循环

3.7 break与continue

3.8 goto语句与标号

四  函数与程序结构

4.1 函数的基本知识

4.2  返回非整型值的函数

4.3 外部变量

4.4 作用域规则

4.5 头文件

4.6 静态变量

4.7 寄存器变量

4.8 程序块结构

4.9 初始化

4.10 递归

4.11 C 预处理器

4.11.1 文件包含

4.11.2 宏替换

4.11.3 条件包含

五   指针与数组

5.1 指针与地址

5.2 指针与函数参数

5.3 指针与数组

5.4 地址算术运算

5.5 字符指针与函数

5.6 字符数组与指针的指针

5.7 多维数组

5.8 指针数组的初始化

5.9 指针与多维数组

5.10 指命令行参数

5.11 指向函数的指针

5.12  复杂声明

六   结构

6.1 结构的基本知识

6.2 结构与函数

6.3 结构与数组

6.4 指向结构的指针

6.5 自引用结构

6.6 表查找

6.7 类型定义(typedef)

6.8 联合

6.9 位字段

七 输入输出

八 UNIX 系统接口

附录A参考手册

A.2 词法规则

A.3 语法符号

A.4 标识符的含义

A.5 对象和左值

A.6 转换

A.7 表达式

A.8 声明

A.9 语句

A.10 外部声明

A.11 作用域与连接

A.12 预处理

A.12.1三字符序列

附录B 标准库

B.1 输入与输出

B.2 字符类别测试

B.3 字符串函数

B.4 数学函数

B.5 实用函数

B.6 诊断

B.7 可变参数表

B.8 非局部跳转

B.9 信号

B.10 日期与时间函数

B.11 与具体实现相关的限制 和

END 写在结尾


一  写在前面

1.1 书籍信息

作者:(美)Brian W. Kernighan / (美)Dennis M. Ritchie

原作名: The C Programming Language

1.2 简单叙述

1978 : The C Programming Language ,第1版

1983 : ANSI 建立 X3J11 委员会 (标准 C)

1988 : The C Programming Language ,第2版

1989 : C89 ,ANSI C 标准出版

笔记为第二版,译者: 徐宝文 / 李志。

笔记中的知识点可能来自书中不同的章节,略过第一章节的记录。

解释与思考部分并不全是书中的内容,也包括经验之谈、网上资料。

二   类型、运算符与表达式

2.1 变量名

变量由字母、数字组成且第一个字母不能是下划线(下划线看作字母)。

内部名长度不要超过31个字符,外部名不要超过6个字符。

C语言中的关键字不能用作变量名。

解释与思考

内部名:在本文件内使用的变量名。

外部名:文件之间相互调用的变量。

变量可以按照不同的依据进行分类,接触最多的有三种分类:

①按照变量类型进行区分,如:  int型变量、long型变量、char型变量等

②按照不同关键字进行区分,如: 静态变量(static)自动变量(auto)寄存器变量(register)、外部变量(extern)

            static修饰的变量有两种情况:

a: 修饰局部变量时,该变量会一直占用存储空间,伴随程序的整个运行周期;

b: 修饰全局变量时,将会限定该变量只在本文件中使用。

auto修饰的变量存在于栈区。

register修饰的变量存在于寄存器中,不能寻址

举例:

            extern修饰的变量有两种情况:

a:该变量在其他文件中定义,想在本文件中使用,需要加extern声明

b:  在变量未定义之前就使用,需要在定义时加extern声明

③按照变量的作用域区分,如全局变量、局部变量

全局变量能够作用与程序的始终

局部变量只能作用于函数体内

三种变量分类之间相互交叉,可以根据变量的不同修饰词对变量的特点进行判断

如:静态变量既可以是全局的也可以是局部的;

int型变量可以全局的也可以是局部的等等;

静态局部变量只能函数内使用,但是存在于 .data 或 .bss段,因此生命周期贯穿程序始终。

———————————————————————————————

2.2 数据类型及长度

基本类型  char、int、float(单精度浮点型)、double(双精度浮点型)

修饰词short、long、unsigned、signed

解释与思考

short 与 long其实是short int与long int 的缩写,用来满足不同长度的整型数

short与int至少16位,long至少32位,长度之间应满足 short =< int =< long

float、double、long double(高精度浮点型)三者之间可以表示为相同的长度或者三种不同的长度,取决于具体实现

———————————————————————————————

2.3 常量

———————————————————————————————

2.4 声明

声明:指明一种数据类型

初始化:变量名后面紧跟一个等号和一个表达式

定义:指定变量所占地址空间的长度

解释与思考

变量的声明都可以使用限定符进行限定,如: constvolatile等

const:

作用是指定的变量不能被修改.

经常谈及:指针常量、常量指针。

int * const p; 指针的指向不能变

const 修饰变量,类型是指针,因此称为指针常量。作用是指针的指向不能改变,但是指向的值可以改变

const int * p; 指针指向的值不能变

const 修饰类型,变量是 p,因此称为常量指针。作用是不能使用该指针修改变量的值,但是指针的指向可以改变.

volatile:

告诉编译器在每次使用该对象值时,都要重新读取它

———————————————————————————————

2.5 算数运算符

算术运算符:+  -  *  /(取整)  %(取余)

———————————————————————————————

2.6 关系运算符与逻辑运算符

关系运算符:>   >=   <   <=   ==   !=

逻辑运算符:&&   ||    !

———————————————————————————————

2.7 类型转换

———————————————————————————————

2.8 自增运算符与自减运算符

自增自减运算符: ++   --。

对于a++和++a类似的自增运算,效果都是将变量加 1 。

当作为前缀运算符时,表达式 ++n 先将 n 的值加 1 ,然后再使用 n 的值,

当作为后缀操作符是,表达式 n++ 是先使用变量 n 的值, 然后再将 n 的值 加 1。

解释与思考

对于一元二元三元运算符的区分是根据运算符结合操作数的个数决定的。

例:a++,++就是一元运算符,a+b,+就是二元运算符。

———————————————————————————————

2.9 按位运算符

位运算符: &   |  ^(异或)  <<   >>  ~

————————————————————————————

2.10 赋值运算符与表达式

赋值运算符: =   +=   -=   *=   /=   %=

————————————————————————————

2.11 条件表达式

三元运算符:   ?:(expr1?expr2:expr3。

首先计算expr1,如果值不等于0(为真),则计算expr2,并以该值作为条件表达式的值,否则计算expr3的值,并以该值作为表达式的值,expr2和expr3只能有一个表达式被计算。

————————————————————————————

2.12 运算符优先级与求值次序

sizeof运算符:计算某种类型在内存中的长度。

逗号(,)运算符: 分割一对表达式按从左到右的顺序进行求值。

运算符有优先级之分,同一优先级,结合性相同。但是C语言没有指定同一运算符中多个操作数的计算顺序。例:

x = f()+ g();

f()可以在g()之前计算也可以在g()之后计算。因此如果函数f或者g改变了另一个函数所用的值,那么x的结果可能会依赖这两个       函数的计算顺序。为了保证特定的计算顺序,可以把中间结果保存在临时变量中

类似,C语言也没有指定函数各参数的求值顺序,例:

printf("%d %d\n", ++n, power(2, n));

在不同的编译器中可能会产生不同的结果,这取决于n的自增运算在power调用之前还是之后。如果想解决这种冲突,可以这样

++n;

printf("%d %d\n", n, power(2, n));

————————————————————————————

三  流控制

3.1 语句与程序块

3.2 if-else

if (表达式)     //表达式为真(非0即真),则执行语句1,表达式值为0,执行else的语句体

{

语句1;   //单独有一条语句时,可以省略大括号;下面的else同理

}

else             //根据需要该else可要可不要,每个 else 与最近的前一个没有 else 配对的且没有在 {} 体内的 if 进行匹配

{

语句2;

}

解释与思考

对于嵌套的 if 语句最好能用合理缩进和相应的 {} 进行逻辑的匹配

——————————————

3.3 else if 语句

if  (表达式)

{

语句;    //单独有一条语句时,可以省略大括号;下面的else if  和 else同理

}

else if  (表达式)

{

语句;

}

else if  (表达式)

{

语句;

}

else

{

语句;

}

解释与思考

这种if语句时编写多路判定的最常用的方法,其中的各个表达式将别一次求值,一旦某个表达式结构为真,则执行与之相关的语句,并且终止整合语句序列的执行。

————————————————————————————

3.4 switch语句

switch (表达式)

{

case 常量表达式: 语句序列;       //语句序列可以是一条也可以是多条

case 常量表达式: 语句序列;

default: 语句序列;                    //该分支可要可不要

}

解释与思考

对于没有 break 关键字的 case 分支中,switch 的表达式会匹配每一个 case 的表达式,如果匹配到则会执行相应的语句序列,且会往下继续匹配直到最后一条分支

————————————————————————————

3.5 while与for循环语句

while(表达式)

{

语句;

}

for(表达式1;表达式2;表达式3)

{

语句;

}

解释与思考

while 和 for 循环语句可以在一定情况下进行相互的转换。

对于 for 循环表达式1 和表达式3 是赋值表达式或者函数调用,表达式2 是关系表达式。

三个表达式的关系是:

————————————————————————————

3.6 do-while循环

do

{

语句;

}

while(表达式);

解释与思考

do-while 循环中,先执行循环体中的语句部分,然后再求表达式的值。如果表达式值为真,则再次执行语句,以此类推。当表达式为假时则循环终止。

————————————————————————————

3.7 break与continue

break 语句可用于从for、while、do-while 等循环中提前退出,就如同 switch 语句中用break可以提前退出一样,能使程序从switch 语句中或者最内层循环中立即跳出。

continue 语句可用于使for、while、do-while语句开始下一次循环的执行。

解释与思考

在 while、do-while 语句中使用 continue 语句将意味着立即执行判断表达式,然后进行下一次循环

在 for 循环中使用 continue 语句将意味着控制转移到表达式3部分,然后再进行下一次的判断、循环

continue语句不用与 switch 语句,某个循环汇包含的 switch 语句中的 continue 语句,将导致下一次循环

————————————————————————————

3.8 goto语句与标号

C语言提供可随意使用的 goto 语句以及标记跳转位置的标号。

解释与思考

标号的命名与变量的命名形式相同,标号后面要紧跟一个冒号

标号的作用域是 goto 所在的函数内

goto 只能用于函数内之间的跳转,对于函数之间的跳转应使用setjmp和longjmp

四  函数与程序结构

4.1 函数的基本知识

返回值类型    函数名(参数声明表)

{

声明和语句

}

解释与思考

函数定义中除函数名以外的各个部分都可以省略,例如:

dummy(){  },该函数不执行任何操作也不返回任何值,常用于构建代码架构时使用。

函数省略返回值类型时默认为 int 类型。

函数之间通信通过参数、函数返回值、以及外部变量进行。

————————————————————————————

4.2  返回非整型值的函数

return (表达式);

解释与思考
函数的返回值有两种表现形式:

return 数据类型

return 表达式

当作为表达式被返回时,表达式的值在返回之前将被转换为函数的类型。

————————————————————————————

4.3 外部变量

定义在任何函数之外的外部,称为外部变量。

解释与思考

外部变量其实就是全局变量。

外部变量提供一种函数之间数据交换的方式。

外部变量的大量使用会导致各个函数之间有大量的数据交换,会对程序的结构产生不良的影响。

————————————————————————————

4.4 作用域规则

外部变量或函数的作用域从声明它的地方开始,到其所在的(待编译的)文件的末尾结束。

变量的定义需要分配存储单元,变量的声明则不需要。

外部变量的定义必须指定数组的长度,但是 extern 声明不一定要指定数组的长度。

外部变量的初始化只能出现在定义中。

构成 C 语言程序的函数与外部变量可以分开进行编译,当 file1 中的函数需要调用 file2 中外部变量时,需要在 file1 中使用 extern 声明 file2 中的外部变量。

解释与思考

变量的定义需要分配存储单元,声明则不需要,声明用于说明变量的属性(主要是变量的类型)。

变量的初始化就是变量的定义+变量的赋值。

————————————————————————————

4.5 头文件

对于中等规模的程序,最好只用一个头文件存放程序中各部分共享的对象,较大的程序需要使用更多的头文件,需要精心的组织这些头文件。

————————————————————————————

4.6 静态变量

通过 static 修饰的外部变量和函数被限定在本文件内使用。

通过 static 修饰的局部变量只能在该函数中使用,但是不会随着函数的退出而释放占用的存储空间。

————————————————————————————

4.7 寄存器变量

register 声明的变量是告诉编译器该变量在程序中的使用频率较高,想将该变量放在机器的寄存器中,但是编译器可以忽略该选项。

register 声明只适用于自动变量和函数的形参。

register 变量不能寻址。

————————————————————————————

4.8 程序块结构

C 语言在函数中可以以程序块结构的形式定义变量。

解释与思考

花括号之间的程序语句称为程序块结构。

程序块内的变量和程序块外的变量没有任何联系,因此程序块内的变量可以和程序块外的变量重名,但是好的程序设计中,应该尽量避免这种情况。

函数的形参也可以与外部变量重名,但是也应该尽量的避免这种情况。

每次进入程序块时,在程序块内的声明及初始化的自动变量都将被初始化,静态变量只在第一次进入程序块时被初始化一次。

————————————————————————————

4.9 初始化

在不进行显示初始化的情况下,外部变量和静态变量将会被初始化为 0,而自动变量和寄存器变量的初值没有定义。

对于外部变量和静态变量来说,初始化的表达式必须是常量表达式且只初始化一次。

对于自动变量和寄存器变量的初始化,可以不是常量表达式,等效于简单的赋值语句,这类变量在每次进入函数或程序块时都将被初始化。

对于数组的初始化,可以省略数组的长度。

如果数组初始化表达式的个数比数组元素少,则对外部变量、静态变量、自动变量来说,没有初始化的元素将被初始化为 0。

对于字符数组的初始化可以使用字符串,可以使用使用花括号加单个字符。

解释与思考

外部变量即为全局变量,自动变量即为局部变量。

对变量的初始化:

例1:

int i = 0;

对数组的初始化:

数组初始化可以在声明的后面紧跟一个初始化表达式列表,初始化表达式列表用花括号括起来,各初始化表达式之间通过逗号分隔,例2:

int arr[5] = {1, 2, 3, 4, 5};

当省略数组数组长度时,编译器将把括号中初始化表达式的个数作为数组的长度,例3:

int arr[] = {1, 2, 3, 4, 5};

如果初始化表达式的个数比数组元素少,则尾部余下的数组成员将被初始化为 0,例4:

int arr[500] = {1, 2};

不管是通过printf 打印还是 gdb 的调试输出信息都可以看出,尾部元素被初始化为0。

对结构的初始化:

对于结构的初始化可以是类型相同的变量,也可以在花括号内按成员依次初始化

————————————————————————————

4.10 递归

递归并不节省存储器的开销,必须考虑递归的深度,防止栈溢出。

————————————————————————————

4.11 C 预处理器

预处理器时编译过程中单独执行的第一个步骤,常用的预处理器指令是:#include、#define。

4.11.1 文件包含

形如 #include "文件名" 或者  #include <文件名> 的行都将被替换为由文件名指定的文件内容。

使用双引号 " " 时在源文件所在位置查找该文件,使用尖括号 < > 时,则将根据相应的规则查找该文件,这个规则同具体的实现有关。

4.11.2 宏替换

宏定义形式: #define 名字 替换文本。

名字与变量的命名方式相同,替换文本可以是任意字符。

程序中所有出现名字记号的地方都将被替换为替换文本。

宏定义可以带参数,但是但使用过程中需要注意,否则会产生错误:

例1:

#define max(A, B) ((A) > (B) ? (A) : (B))

max(i++, j++) 会对 i 和 j 进行计算两次;

例2:

#define square (x)    x*x

square (x+1)  并不是 x+1 的平方,这种错误应该使用括号进行规避。

宏定义的两个需要注意的符号:  # 和 ##。

例1:

#define tempfile(dir)   #dir  "%s"

tempfile(/usr/temp)   将被替换为 "/usr/temp/" "%s" ,随后该结构将被连接为一个单个的字符串。

例2:

#define cat(x, y) x ## y

cat(var, 123)  将被替换为 var123。

4.11.3 条件包含

可以使用条件语句对预处理本身进行控制。

#if 语句:

#if 语句对其中的常量整型表达式(不能包含sizeof、类型转换运算符、enum常量)进行求值,若该表达式的值不等于 0,则包含其后的各行,直到遇到 #endif 或者 #elif 或者 #else 语句为止。在 #if 语句中可以使用 defined(名字),该表达式的值遵循下列规则:当名字已经定义时,其值为 1,否则,其值为 0。

例1:

#if !defined(HDR)

#define HDR

/*hrd.h 文件的内容放在这里*/

#ednif

#ifdef 与 #ifndef 语句:

用来测试某个名字是否已经定义。

例2:

#ifndef(HDR)

#define HDR

/*hrd.h 文件的内容放在这里*/

#ednif

例1 和例2 第一次包含头文件 hdr.h 时,将定义名字 HDR,此后再次包含该头文件时,会发现该名字已经定义,这样将直接跳转 #endif 处。这样的方式可以比避免多次重复的包含同一文件。

五   指针与数组

指针是一种保存地址的变量。

5.1 指针与地址

对变量取地址用运算度 &,取指针指向的地址取内容用 * 。

解释与思考5.1

已知:  int  a = 7; int *p = &a;

区分:  *p +1 、(*p)++ 、++*p 、*p++ 、*++p

  • ++ 和 * 的优先级一样
  • ++ 和 * 的运算符为右至左的结合性,( man  operator)
  • 相同优先级的运算符拥有相同的结合性,这样可以避免运算时的混淆

① *p +1   : 取p指向地址的值然后值再加一,因此 *p+1 = 8

② (*p)++  : 由于括号优先级较高,所以结果同 ①

③ ++*p   : 由于 ++ 是右到左的结合性,因此++ 会结合 *p的值,

因此 ++*p = 8

④*p++    : 由于 * 是右到左的结合性,因此会结合p, ++ 也是右到左的结合性,但是 ++ 右边无操作数,因此会结合 p,又由于 ++ 作为了后缀操作符,因此会在对 p 进行过取值运算后在自增,指向另一块地址。

⑤*++p    : 由于 ++ 是右到左的结合性,因此++ 会结合 p的值,对 p 进行自增,使 p 指向了另一块地址空间,然后 * 运算符对另一块地址取值。当然这已经属于对内存的非法操作了,是否报错依据各自的编译器。

5.2 指针与函数参数

  • C 语言是以传值的方式将参数传递给被调函数。因此,被调函数不能直接修改传入的变量的值。
  • C 语言中通过 运算符 & 可以将变量的地址的作为一个值传给被调函数,函数中可以通过运算符 * 对变量取值或者修改。

5.3 指针与数组

  • 数组名是数组首元素的地址。
  • 通过数组下标所能完成的任何操作都可以通过指针来实现。
  • 如果 p 是一个指向数组中某个元素的指针,那么 p++ 将对 p进行自增运算并指向下一个元素,而 p+i 将对p 进行加 i 的增量运算,使其指向指针p 当前所指向的元素之后的第 i 个元素。

5.4 地址算术运算

  • 指针有意义的初始化只能是0 或者是表示地址的表达式,对后者来说,表达式所代表的地址必须是在此前已经定义的具有适当类型的数据的地址。
  • 指针与整数之间不能相互转换,但是 0 是唯一的例外:常量 0 可以复制给指针,指针也可以和常量 0 进行比较,程序中经常使用符号常量 NULL 代替常量 0 ,这样更便于清晰地说明 0 是指针的一个特殊值。
  • 无论指针 p 指向的对象是何种类型,p + n 表示指针 p 当前指向的对象的第 n 个对象的地址。
  • 有效的指针运算包括相同类型指针之间的赋值预算;指针同整数之间的加法或者减法运算;指向相同数组中元素的两个指针间的减法或者比较运算;将指针赋值为 0 或者 指针 与 0 之间的比较运算。

5.5 字符指针与函数

char * p = “ now is the time”

  • 上述声明中 p 是一个指针,其初值指向一个字符串常量,之后可以修改指针的值以指向其它地址,但是试图修改字符串的内容,结果是没有定义的。
  • 标准库中 strcmp、strcpy 等函数均使用到字符指针。

5.6 字符数组与指针的指针

指针数组: char * pArr[10];

  • pArr 是一个指针数组,每个数组元素都是一个字符指针。

5.7 多维数组

在 C 语言中,二维数组实际上是一种特殊的一维数组,每一元素都是其实都是一个一维数组。

5.8 指针数组的初始化

char * pArr[] =

{

“i am a programer” ,

“you ?” ,

“ i gass ...”

};

  • pArr是一个数组,数组的每个元素都是一个char* 的指针。

5.9 指针与多维数组

Int  a[10][20];

Int  *b[10];

  • 对 a 来说分配了200 个int 类型的存储空间。
  • 对 b 来说,只是分配了 10 个int类型的指针,并且没有对他们初始化,假如 b 的每个元素都指向一个具有 20 个元素的数组,那么编译器就要为它分配 200 个int 类型长度的存储空间。
  • 指针数组的优点是数组的每一行长度可以不同,也就是说,b 的每个元素不必都指向一个具有 20 个元素的向量,某些元素可以指向具有 2 个元素的向量,某些元素可以指向具有50 个元素的向量,而某些元素可以不指向任何向量。
  • 指针数组最频繁的用处是存放具有不同长度的字符串。

5.10 指命令行参数

C 语言环境中,可以在程序开始执行时将命令行参数传递给程序。

  • argc:表示运行程序时命令行中参数的数目
  • argv:指向字符串数目的指针
  • argc 的值至少是 1
  • argv[0] 是启动程序的程序名,依次是 argv[1]、argv[2] ...
  • ANSI 标准规定argv[argc] 的值必须是一空指针

5.11 指向函数的指针

Int (*cmp) (void*, void*)

cmp是一个指向函数的指针,该函数有两个void* 类型参数,器返回值为 int。

5.12  复杂声明

  • 指针函数: int *f (int, int),f 是一个函数,函数的返回值是int *。
  • 函数指针: int (*pf)(int, int),pf 是一个指针,指针指向函数入口地址,该函数拥有两个int 类型的参数,返回值是 int。

解释与思考5.12

介绍一下书中的两个复杂声明:

char (* (*x())[] ) ()

  • X 是一个函数,它返回一个指针,指针指向一个一维数组,该数组的每个元素为指针类型,这些指针分别指向多个函数,这些函数的返回值为char类型

char (*(*x[3])())[5]

  • x 是一个有 3 个成员数组,数组的每个元素都是一个指针,该指针都指向一个函数,每个函数的返回值也是一个指针,函数返回值的指针指向一个一维数组,数组是由五个char 类型字符组成。

六   结构

结构是一个或者多个变量的集合

6.1 结构的基本知识

声明结构体类型:

struct poind {

Int  x;

Int y;

};

定义结构体变量:

① 定义结构变量x,y,z

struct poind {

........

}x,  y,  z;

② 定义结构变量pt

struct poind pt;

结构体初始化:

struct point maxpt = {320,200};

  • 关键字struct 引入结构声明,结构声明有包含在花括号内的一系列声明组成。
  • struct 后面的名字是可选的,成为结构标记。
  • 结构中定义的变量成为成员,结构成员、结构标记、和普通变量可以采用相同的名字。
  • 不同结构中的成员可以使用相同的名字。

6.2 结构与函数

  • 结构的几种合法操作:

作为一个整体复制和赋值;

通过 & 运算符取地址;

访问其成员。

  • 对与结构体变量访问成员使用 运算符 . ,对与结构体指针访问成员使用 运算符 ->
  • 复制和赋值包括函数传递参数以及从函数返回值:

例如:从传入函数的参数和返回值都是结构体类型

struct poind addpoind(struct poind p1,  struct poind p2)

{

p1.x += p2.x;

p1.y += p2.y

return  p1;

}

传入的参数直接赋值给 p1、p2,同时返回结构类型

6.3 结构与数组

定义结构体数组

struct key

{

char *word;

int count;

}keytab[NKEYS];

struct key

{

char *word;

int count;

};

struct key keytab[NKEYS];

定义并初始化

struct key

{

char *word;

int count;

}keytab[] = {

“auto”, 0,

“break”, 0,

“char”, 0,

“const”, 0

};

初值可以用花括号 {} 括起来:

{“auto”, 0},

{“break”, 0},

{“const”, 0}

6.4 指向结构的指针

如果 p 是一个指向结构的指针,则对 p 的算术运算需要考虑结构的长度,所以 p++执行时,将在 p 地址上加上一个结构的长度

6.5 自引用结构

统计输入单词出现的次数,使用自引用结构组成一种树的数据结构:

struct tnode{

char *word;

int count;

sturct tnode *left;

struct tnode *right;

};

解释与思考6.5

自引用结构需要用结构体指针,使用变量会无法确定结构体的大小。

6.6 表查找

6.7 类型定义(typedef)

C 语言使用typedef 建立新的数据结构类型名。

typedef int Length;

Length len, maxlen;

Length *lengths[];

与使用int 完全相同

typedef int (*PFI) (char*, char*);

该语句定义了类型PFI 是一个指向函数的指针,该函数具有两个 char* 类型的参数,返回值为 int 类型。

6.8 联合

使用联合可以在单块存储区中管理不同类型的数据,而不需要在程序中嵌入任何同机器有关的信息。

定义:

union u_tag {

int ival;

float fval;

char *sval;

}u;

上述联合体中的任何一种类型的对象都可以赋值给 u,且可以使用在随后的表达式中,但是必须保证是一致的:读取的类型必须是最近一次存入的类型。如果保存的类型与读取的类型不一致,其结果取决于具体的实现。

联合的访问方式和结构相同:

联合名.成员

联合指针->成员

6.9 位字段

例子:

sturct {

unsigned int is_keyword : 1;

unsigned int is_extern : 1;

unsigned int is_static : 1;

}flags;

这里定义了一个变量 flags,它包含 3 个一位的字段。冒号后的数字便是字段的宽度。字段被声明为 unsigned int 类型,保证它们是无符号量。

单个字段的引用方式与其它结构成员相同:

flags.is_extern = flags.is_static = 1;

flags.is_extern = flags.is_static = 0;

某些机器上字段的分配是从字的左端至右端,而某些则相反。这意味着尽管字段对维护内部定义的数据结构很有用,但是在选择外部定义数据的情况下,必须仔细考虑那段优先的问题。依赖这些因素的程序是不可移植的。

字段没有地址,因此不能对它们使用 & 运算符。

七 输入输出

八 UNIX 系统接口

附录A参考手册

A.2 词法规则

A.3 语法符号

A.4 标识符的含义

A.5 对象和左值

A.6 转换

A.7 表达式

A.8 声明

A.9 语句

A.10 外部声明

A.11 作用域与连接

A.12 预处理

A.12.1三字符序列

??= #

??( [

??< {

??/ \

??) ]

??> }

??' ^

??! |

??- ~

 解释与思考

三字符序列以 ?? 开头另加一个字符来表示其它字符。

当程序中出现了意想不到的异常现象时,且观察程序周围有 ?? 字符时,可以考虑一下三字符序列。例如:(-trigraphs 是为了       使能三字符的处理)

附录B 标准库

B.1 输入与输出

B.2 字符类别测试

B.3 字符串函数

B.4 数学函数

B.5 实用函数

B.6 诊断

B.7 可变参数表

B.8 非局部跳转

B.9 信号

B.10 日期与时间函数

B.11 与具体实现相关的限制 和

END 写在结尾

C语言程序设计---读书笔记汇总(整理中)相关推荐

  1. c语言程序设计读书笔记3000字,C语言程序设计读书笔记题目

    读书笔记注意事项: 1. 读书笔记要求至少有六个题目,在一类.二类.三类题目中各选两题,具体题目选择由学生自行选择. 2. 每个题目必须包含所选题目,以及具体题目的程序实现过程,要求每行语句后都需要有 ...

  2. 魏振瀛民法学笔记汇总整理

    <民法学笔记汇总整理(精华版) 第一篇:民法总论 第一章:民法概述 第一节:民法的含义 一,民法的概念: 民法是调整平等主体的自然人.法人.其他组织之间的财产关系和人身关系的法律规范的总和. 1 ...

  3. Oracle PL/SQL 程序设计读书笔记 - 第7章 使用数据

    Oracle PL/SQL 程序设计读书笔记 - 第7章 使用数据 Oracle PL/SQL 程序设计读书笔记 - 第7章 使用数据 7.1 程序数据的命名 PL/SQL要求在给数据结构命名的时候应 ...

  4. Go语言实战读书笔记

    2019独角兽企业重金招聘Python工程师标准>>> Go语言实战读书笔记 第二章 通道(channel).映射(map)和切片(slice)是引用类型.引用类型的对象需要使用ma ...

  5. Oracle PL/SQL 程序设计读书笔记 - 第14章 DML和事务管理

    Oracle PL/SQL 程序设计读书笔记 - 第14章 DML和事务管理 Oracle PL/SQL 程序设计读书笔记 - 第14章 DML和事务管理 ACID原则:即一个事务具有原子性.一致性. ...

  6. 2015电大c语言,2015电大本科C语言程序设计A试题汇总.doc

    2015电大本科C语言程序设计A试题汇总 2015年电大本科<C语言程序设计A>一.单选题 1.在每个C语言程序中都必须包含有这样一个函数,该函数的函数名为 A . A. main B. ...

  7. c语言用户自己建立数据类型,C语言程序设计学习笔记--用户建立数据类型

    C语言程序设计学习笔记--用户建立数据类型. 9.1定义和使用结构体变量 1.定义:C语言允许用户自己建立不同类型数据组合成的组合型数据类型就是结构体 2.形式: struct 结构体名 { 成员表列 ...

  8. C语言程序设计学习笔记:P1-程序设计与C语言

    本系列博客用于记录学习浙江大学翁恺老师的C语言程序设计,系列笔记链接如下: C语言程序设计学习笔记:P1-程序设计与C语言 C语言程序设计学习笔记:P2-计算 C语言程序设计学习笔记:P3-判断 C语 ...

  9. C语言程序设计学习笔记:P3-判断

    本系列博客用于记录学习浙江大学翁恺老师的C语言程序设计,系列笔记链接如下: C语言程序设计学习笔记:P1-程序设计与C语言 C语言程序设计学习笔记:P2-计算 C语言程序设计学习笔记:P3-判断 C语 ...

最新文章

  1. 理解GRUB2工作原理及配置选项与方法
  2. 统计简单学_回归分析
  3. 编写程序,输入某年某月,求该月有多少天
  4. pycryptodom的源码安装
  5. 操作系统常用调度算法
  6. hive sql 学习笔记
  7. Linux终端乱码的解决办法
  8. 初识图机器学习(part5)--图表示学习2.0
  9. c# vs2005 多线程中调用窗体控件 (摘)
  10. 夏令营提高班上午上机测试 Day 1 解题报告
  11. servlet笔试题java,Java推荐!Servlet面试题和答案汇集
  12. 2020-09-24L1-016 查验身份证 (15分) 一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下: 首先对前17位数字加权求和,权重分配为:{7,
  13. android mkdir失败_在/ sdcard中创建目录失败
  14. Python实现三维数据(x, y, z)的索引——即通过(x, y)的值索引z的值
  15. 【隧道应用-1】netsh端口映射内网
  16. 大学生三个痛点及分析
  17. iOS支付指南:POS终端刷卡流程、银联55域TLV子域信息说明、银联前置、NFC
  18. abap源代码---正常生产订单打印/两种选择
  19. STC89c51利用esp8266发微信消息,POST例程
  20. 一堆小众实用工具网站,建议收藏!

热门文章

  1. 【做题笔记】P2327 [SCOI2005]扫雷
  2. 淘宝API商品详情接口,通过商品ID获取商品名称,淘宝主图,价格,颜色规格尺寸,库存,SKU等
  3. 怎么保存网页为html格式,怎样保存网页部分内容为html格式?
  4. 杭州电子科技大学计算机录取分数线,杭州电子科技大学历年录取分数线多少及各省最低投档线统计表...
  5. 利用WITH AS改写SQL
  6. 51nod3148 松鼠聚会
  7. WooCommerce最新2.3.10汉化简体中文版语言包mo免费下载
  8. DVD刻录工具(anymp4 dvd creator 7)pjb v7.2.58
  9. 安卓aab格式加固、签名和安装命令(超简单)
  10. AGC001E BBQ Hard [dp]