C和指针读书笔记——部分简介

这篇博客详细介绍了C语言的重要性和基本概念,包括字符、注释、预处理指令、main函数等。深入探讨了指针的使用,如间接访问、指针运算和动态内存分配。此外,还涉及了函数的参数传递、数组、字符串、结构体和联合体,以及预处理器的使用。文章强调了编程提示,如避免隐式声明和使用typedef创建新类型名。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C和指针读书笔记——部分简介

标签(空格分隔): 读书笔记


1 C语言的重要性

1.C语言效率高。
2.C语言具有可移植性。

1.1 重排字符

1.1.1 空白和注释

注释以符号/开始,以符号**/结束。注释不能被嵌套。但是可以用:

#if 0
    statements
#endif

在#if和#endif之间的程序就可以有效地从程序中去除,不论之间有没有其他注释。

1.1.2 预处理指令

就是.h文件,在main主函数中声明

1.1.3 main函数
int main(void)
{
}

主要讲了printf的用法。

1.1.4 read_column_number 函数

主要讲scanf用法。

1.2 补充

1.3 编译

1.4 总结

1.5 警告的总结

  • 在scanf函数的标量参数前未添加&字符。
  • 机械地把printf函数的格式代码照搬于scanf函数。
  • 在应该使用&&操作符的地方误使用了&操作符。
  • 误用=操作符而不是==操作符来测试相等性。

1.6 编程提示的总结

  • 使用#inculde指令避免重复声明。
  • 使用#define指令给常量值取名。
  • 在#include文件中放置函数原型。
  • 在while或if表达式中蕴含复制操作。
  • 如何编写一个空循环体。
  • 始终要进行坚持,确保数组不越界。

2 基本概念

2.1 环境

2.1.1 翻译
2.1.2 执行
  • 程序必须载入到内存中。
  • 程序开始执行。
  • 开始执行程序代码。
  • [x] 在绝大数机器里,程序将使用一个运行时堆栈(stack),它用来存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程中将一直保留他们的值。
  • 程序的终止。

2.2 词法规则

2.2.1 字符
  • [x] 注意使用转义序列
  • \? 在书写连续多个问号时使用,防止他们被解释为三个字母词。
  • \” 用于表示一个字符串常量内部的双引号。
  • \’ 用于表示字符常量’。
  • \\ 用于表示一个反斜杠,防止它被解释为一个转义序列符。
  • \a 警告字符。
  • \b 退格键。
  • \f 进纸字符。
  • \n 换行符。
  • \r 回车符。
  • \t 水平制表符。
  • \v 垂直制表符。
2.2.2 注释
2.2.3 自由形式的源代码
  • 相邻的标记之间必须出现一个至多个空白字符(或注释),不然他们可能被解释为单个标记。
3.3.4 标识符
  • 标识符就是变量、函数、类型等的名字,他们由大小写字母、数字和下划线组成,不能以数字开头。
  • 标识符不能使用关键字。
2.2.5 程序的形式

2.3 程序风格

让人更加方便的读写代码

3 数据

3.1 基本数据类型

  • 在C语言中,仅有4种基本数据类型——整型、浮点型、指针和聚合类型(如数组和结构等)。
3.1.1 整型家族
  • 包括字符、短整型、整型和长整型,都分为有符号(singed)和无符号(unsigned)两种版本。
  • 长整型至少应该和整型一样长,而整型至少应该和短整型一样长。

一、整型字面值
二、枚举类型

3.1.2 浮点类型
  • 浮点数家族包括float、double和long double类型。
  • 规定:long double至少和double一样长,而double至少和float一样长。
  • 所有浮点类型至少能够容纳从10371037
3.1.3 指针

一、指针常量
二、字符串常量

3.2 基本声明

形式:
说明符(一个或多个) 声明表达式列表
例如:

int a;
cha b;
3.2.1 初始化

例如:

int a = 0;
3.2.2 声明简单数组

例如:

int values[20];
3.2.3 声明指针

例如:

int *a;
3.2.4 隐式声明

3.3 typedef

  • 使用typedef比#define来创建新的类型名要好,因为后者无法处理指针类型。

3.4 常量

3.5 作用域

  • 编译器可以确认4中不同类型的作用域——文本作用域、代码作用域、函数作用域和原型作用域。
  • 标识符声明的位置决定它的作用域。
3.5.1 代码作用域
  • 位于一对花括号之间的所有语句称为一个代码块。任何在代码块的开始位置声明的标识符都具有代码块作用域。
  • 函数形参的作用域开始于形参的声明处,位于函数体之外。
3.5.2 文件作用域
  • 任何在所有代码块之外声明的标识符都具有文件作用域,它表示这些标识符从他们声明之处直到它所在的源文件结尾处都是可以访问的。
3.5.3 原型作用域
  • 原型作用域只适用于在函数原型中声明的参数名。
3.5.4 函数作用域
  • 一个函数中所有语句标签必须唯一。

3.6 链接属性

  • 链接属性一共有三中——external(外部)、internal(内部)和none(无)。

3.7 存储类型

  • 凡是在任何代码块之外声明的变量总是存储于静态内存中,也就是不属于堆栈的内存,这类变量称为静态(static)内存。
  • 在代码块内部声明的变量的缺省存储类型是自动的(automatic),也就是说它存储于堆栈中,称为自动(auto)变量。
  • 函数的形式参数不能声明为静态,因为实参总是在堆栈中传递给函数,用于支持递归。

3.8 static关键字

3.9 作用域、存储类型示例

3.12 编程提示的总结

  • 为了保持最佳的可移植性,把字符的值限制在有符号字符和无符号字符范围的交集之内,或者不要在字符上致谢算数运算。
  • 用他们在使用时最自然的形式来表示字面值。
  • 不要把整型值和枚举值混在一起使用。
  • 不要依赖隐式声明。
  • 在定义类型的新名字时,使用typedef而不是#define。
  • 用const声明其值不会被修改的变量。
  • 使用名字常量而不是字面值常量。
  • 不要在嵌套的代码块之间使用相同的变量名。

4 语句

4.1 空语句

4.2 表达式语句

4.3 代码块

4.4 if语句

语法:

if(expression)
    statement
else
    statement

4.5 while语句

语法:

while(expression)
    statement
4.5.1 break和continue语句
  • break用于永久终止循环。
  • continue用于永久种植当前的那次循环。
4.5.3 while语句的执行过程

4.6 for语句

语法:

for(expression1;expression2;expression3)
    statement

4.7 do语句

语法:

do
    statement
while(expression);
  • 当你需要循环体至少执行一次时,选择do。

4.8 switch语句

语法:

switch(expression)
    statement
4.8.1 switch中的break语句
  • 如果在switch语句执行中遇到了break语句,执行流就会立即调到语句列表的末尾。
4.8.2 default子句
  • 当switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行。所以,每个switch语句中只能出现一条default子句。
4.8.3 switch语句的执行过程

4.9 goto语句

语法:

goto 语句标签;
  • 一般使用goto来结束深层循环。
    如:
while(condition1){
    while(condition2){
        while(condition3){
            if(some disaster){
                goto quit;
            }
        }
    }
}
quit:;

5 操作符和表达式

5.1 操作符

5.1.1 算数操作符
+ - * / %
5.1.2 移位操作符
左移位操作符为<<,右移位操作符为>>。
5.1.3 位操作符
位操作符有:& | ^
5.1.4 赋值
赋值操作符:=
复合赋值符:+= -= *= /= %= <<= >>= &= ^= |=
5.1.5 单目操作符
! ++ - & sizeof ~ -- * 
5.1.6 关系操作符
> >= < <= != ==
5.1.7 逻辑运算符
&& ||
5.1.8 条件操作符
expression1?expression2:expression3
5.1.9 逗号操作符
expression1,expression2,...,expressionN
  • 逗号操作符将两个或多个表达式分割开来。这些表达式自左向右逐个进行求值,整个逗号表达式的值及时最后那个表达式的值。
5.1.10下标引用、函数调用和结构成员

5.2 布尔值

规则:零是假,任何非零值皆为真。

5.3 左值和右值

5.4 表达式求值

5.4.1 隐式类型转换
5.4.2 算数转换
  • 如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另一个操作数的类型,否则操作就无法进行。
5.4.3 操作符的属性
5.4.4 优先级和求值的顺序

6 指针

6.1 内存和地址

  • 内存中的每个位置由一个独一无二的地址标识。
  • 内存中的每个位置都包含一个值。

6.2 值和类型

  • 不能简单地通过检查一个值得位来判断它的类型。为了判断值的类型(以及它的值),你必须观察程序中这个值的使用方式。

6.3 指针变量的内容

6.4 间接访问操作符

通过一个指针访问它所指向的地址的过程称为间接访问(indirection)或解引用指针(dereferencing the pointer)。

6.5 末初始化和非法的指针

6.6 NULL指针

6.7 指针、间接访问和左值

  • 指针变量可以作为左值,并不是因为他们是指针,而是因为他们是变量。

6.8 指针、间接访问和变量

*&a = 25;

6.9 指针常量

6.10 指针的指针

6.11 指针表达式

6.13 指针的运算

  • 一个指针加1,它会根据类型进行调整,指向下一个类型。
6.13.1 算术运算

第一种形式
指针 ± 整数

  • 标准定义这种形式只能用于指向数组中某个元素的指针。

第二种形式
指针 - 指针

  • 只有当两个指针都指向同一个数组中的元素时,才允许从一个指针减去另一个指针。
6.13.2 关系运算
< <= > >=
  • 前提是他们都指向同一个数组中的元素。

7 函数

7.1 函数定义

函数的定义就死函数体的实现
语法:

返回值类型 函数名(形式参数){
    代码块
}

7.2 函数声明

7.2.1 原型
返回值类型 函数名(形式参数);
  • 现在函数原型具有文件作用域,所以原型的一份拷贝可以作用于整个源文件,较之在该函数每次调用前单独书写一份函数原型药容易得多。
  • 现在函数原型只书写一次,这样就不会出现多份原型的拷贝之间的不匹配现象。
  • 如果函数的定义进行了修改,我们只需要修改原型,并重新编译所有包含了该原型的源文件即可。
  • 如果函数的原型同时也被#include指令包含到定义函数的文件中,编译器就可以确认函数原型与函数定义的匹配。
7.2.2 函数的缺省认定
  • 所有的函数都应该具有原型,尤其是那些返回值不是整型的函数,记住,值的类型并不是值的内在本质,而是取决于它被使用的方式。

7.3 函数的参数

  • 传递给函数的标量参数是传值调用的。
  • 传递给函数的数组参数在行为上就像是通过传址调用的那样。

7.4 ADT和黑盒

7.5 递归

递归函数就是直接或者间接调用自身的函数。

7.5.1 追踪递归函数
7.5.2 递归与迭代

阶乘
递归举例:

long factorial(int n ){
    if(n <= 0){
        return 1;
    }else{
        return n * factorial(n-1);
    }
}

迭代举例:

long factorial(int n ){
    int result = 1;
    while(n > 1){
        result *= n;
        n -= 1;
    }
    return result;
}

7.6 可变参数列表

7.6.1 stdarg宏

可变参数列表是通过宏来实现的,这些宏定义于stdarg.h头文件,它是标准库的一部分。

7.6.2 可变参数的限制
  • 注意,可变参数必须从头到尾按照顺序逐个访问,如果你在访问了几个可变参数后想半途终止,这是可以的。但是,如果你想一开始就访问参数列表中间的参数,那是不行的。

8 数组

8.1 一维数组

8.1.1 数组名
8.1.2 下标引用
8.1.3 指针与下标
8.1.4 指针的效率

指针有时比下标更有效率,前提是他们被正确的使用

  • 当你根据某个固定数目的增量在一个数组中移动时,使用指针变量将比使用下标产生更高的代码。当这个增量是1并且机器具有地址自动增量模型时,这点表现得更为突出。
  • 声明为寄存器变量的指针通常比位于静态内存和堆栈中的指针效率更高(具体提高的幅度取决于你所使用的机器)。
  • 如果你可以通过测试一些已经初始化并经过调整的内容来判断循环是否应该终止,那么你就不需要使用一个单独的计数器。
  • 那些必须在运行时求值的表达式较之诸如&array[SIZE]或array+SIZE这样的常量表达式往往代价更高。
8.1.5 数组和指针
8.1.6 作为函数参数的数组名
8.1.7 声明数组参数
int strlen(char *string);
int strlen(char string[]);

这两个函数原型是相等的。

8.1.8 初始化
9.1.9 不完整的初始化

编译器只知道初始值不够,但它无法知道缺少的是哪些值,所以,只允许省略最后几个初始值。

8.1.10 自动计算数组长度
int a[] = {1,2,3}

上面自动计算出数组长度是3。

8.1.11 字符数组的初始化
char a[] = "Hello";

8.2 多维数组

int a[5][3];
8.2.1 存储顺序
8.2.2 数组名
8.2.3 下标
8.2.4 指向数组的指针
8.2.5 作为函数参数的多维数组
8.2.6 初始化
int a[2][3] = {{1,2,3},{4,5,6}};

8.3 指针数组

9 字符串、字符和字节

9.1 字符串基础

9.2 字符串长度

  • 注意strlen返回一个类型为size_t的值,这个类型是在头文件stddef.h中定义的,它是一个无符号整型类型。

9.3 不受限制的字符串函数

9.3.1 复制字符串

用于复制字符串的函数是strcpy,它的原型如下所示:

char *strcpy(char *dst, char const *src);

这个函数把参数src字符串复制到dst参数。

  • 注意:程序员必须保证目标字符数组的空间足以容纳需要复制的字符串。
9.3.2 链接字符串

要想把一个字符串添加(链接)到另一个字符串的后面,你就可以使用strcat函数,它的原型如下:

char *strcat(char *dst, char const *src);
9.3.3 函数的返回值
9.3.4 字符串比较

库函数strcmp用于比较两个字符串,它的原型如下:

int strcmp(char const *s1, char const *a2);

9.4 长度受限的字符串函数

9.5 字符串查找基础

9.5.1 查找一个字符

使用strchr和strrchr函数,他们的原型如下:

char *strchr(char const *str, int ch);
char *strrchr(char const *str, int ch);
9.5.2 查找任何几个字符

用strpbrk函数,原型如下:

char *strpbrk(char const *str, char const *group);
9.5.3 查找一个子串

用函数strstr函数,原型如下:

char *strstr(char const *s1, char const *s2);

9.6 高级字符串查找

9.6.1 查找一个字符串前缀

用函数strspn和strcspn,原型如下:

size_t strspn(char const *str, char const *group);
size_t strcspn(char const *str, char const *group);
9.6.2 查找标记

使用函数strtok,原型如下:

char *strtok(char *str, char const *sep);

9.7 错误信息

9.8 字符操作

9.8.1 字符分类
9.8.2 字符转换

toupper函数返回其参数的对应大写形式,tolower函数返回其参数的对应小写形式,原型如下:

int tolower(int ch);
int toupper(int ch);

9.9 内存操作

10 结构和联合

10.1 结构基础知识

10.1.1 结构声明

在声明结构时,必须列出它包含的所有成员。

struct tag {member-list}variable-list;

声明结构时可以使用一种良好技巧,用typedef创建一种新的类型,例如:

typedef struct{
    int a;
    char b;
    float c;
}Simple;

之后就直接可以使用Simple进行定义变量。

10.1.2 结构成员
10.1.3 结构成员的直接访问
10.1.4 结构成员的间接访问
10.1.5 结构的自引用
10.1.6 不完整的声明
10.1.7 结构的初始化

举例:

struct INIT_EX{
    int a;
    short b[10];
    simple c;
    }x = {
        10,
        {1,2,3,4,5},
        {25,'x',1.9}
    };

10.2 结构、指针和成员

10.2.1 访问指针
10.2.2 访问结构
10.2.3 访问结构成员

10.3 结构的存储分配

  • 只有当存储成员需要满足正确的边界对齐要求时,成员之间才可能出现用于填充的额外内存空间。

10.4 作为函数参数的结构

10.5 位段

10.6 联合

联合的所有成员引用的是内存中的相同位置。

10.6.1 变体记录
10.6.2 联合的初始化

如:

union{
    int a;
    float b;
    char c[4];
} x = {5};

把x.a初始化为5。

10.9 编程提示的总结

  • 把结构标签声明和结构的typedef声明放在头文件中,当源文件需要这些声明时可以通过#include指令把他们包含进来。
  • 结构成员的最佳排列形式并不一定就是考虑边界对齐而浪费内存空间最少的那种排列形式。
  • 把位段成员显式地声明为signed或unsigned int类型。
  • 位段是不可移植的。
  • 位段使源代码中位的操作表达得更为清楚。

11 动态内存分配

11.1 为什么使用动态内存分配

11.2 malloc和free

原型如下:

void *malloc(size_t size);
void free(void *pointer);

11.3 calloc和realloc

原型如下:

void *calloc(size_t num_elements, size_t element_size);
void realloc(void *ptr, size_t new_size);
  • calloc也用于分配内存。malloc和calloc之间的主要区别是后者在返回指向内存的指针之前把它初始化为0。
  • realloc函数用于修改一个原先已经分配的内存块的大小。

11.4 使用动态分配的内存

一般使用:

int *pi;
pi = malloc(25 * sizeof(int));

11.5 常见的动态内存错误

11.9 编程提示总结

  • 动态内存分配有助于消除程序内部存在的限制。
  • 使用sizeof计算数据类型的长度,提高程序的可移植性。

12 使用结构和指针

12.1 链表

  • 链表(linked list)就一些包含数据的独立数据结构(通常称为节点)的集合。

12.2 单链表

12.2.1 在单链表中插入
12.2.2 其他链表操作

12.3 双链表

13 高级指针话题

13.1 进一步探讨指向指针的指针

13.2 高级声明

13.3 函数指针

13.3.1 回调函数
13.3.2 转移表

13.4 命令行参数

13.4.1 传递命令行参数
13.4.2 处理命令行参数

13.5 字符串常量

14 预处理器

14.1 预定义符号

14.2 #define

define name stuff

有了这条命令以后,每当有符号name出现在这条指令后面时,预处理器就会把它替换成stuff。

14.2.1 宏
#define name(parameter-list) stuff
14.2.2 #define替换
14.2.3 宏与函数

例如在两个表达式中寻找其中较大(或较小)的一个:

#define MAX(a, b) ((a) > (b) ? (a) : (b))
14.2.4 带副作用的宏参数
14.2.5 命名约定
14.2.6 #undef

这条预处理指令用于移除一个宏定义。

#undef name
14.2.7 命名行定义

14.3 条件编译

14.3.1 是否被定义
14.3.2 嵌套指令

14.4 文件包含

14.4.1 函数库文件包含
#include <filename>
14.4.2 本地文件包含
#include "filename"
14.4.3 嵌套文件包含

14.7 警告的总结

  • 不要在一个红定义的末尾加上分号,使其成为一条完整的语句。
  • 在宏定义中使用参数,但忘记在他们周围加上括号。
  • 忘记在整个宏定义的两倍加上括号。

15 输入/输出函数

16 标准库函数

17 经典抽象数据类型

18 运行时环境

C语言教程(原书第4版) 《c语言教程(原书第4版)》是一本优秀的c程序设计语言教材,完整描述了ansi c语言及其语法特性,并对c语言的高级特性应用作了深入阐述,介绍了从c到c++java过渡的相关知识。《c语言教程(原书第4版)》的一个鲜明特色就是结合大量示例描述c语言的重要特征,并对很多工作代码给出了逐步的分析,以这种独特的教学方法向读者解释新接触的编程元素及一些惯用法。   《c语言教程(原书第4版)》系统、完整,可作为c语言的参考手册,也非常适合作为学习c语言的入门高级课程教材。 前言 第0章 从零开始 0.1 为什么要用c 0.2 ansi c标准 0.3 从c到c++ 0.4 从cc++到java 第1章 c语言概述 1.1 编程预备知识 1.2 程序输出 1.3 变量、表达式赋值 1.4 使用#define#include 1.5 使用printf()scanf() 1.6 控制流 1.7 函数 1.8 数组、字符串指针 1.8.1 数组 1.8.2 字符串 1.8.3 指针 1.9 文件 1.10 与操作系统有关的内容 1.10.1 编写运行c程序 1.10.2 中断程序 1.10.3 输入文件尾标志 1.10.4 输入输出的重定向 1.11 总结 1.12 练习 第2章 词法元素、操作c系统 2.1 字符词法元素 2.2 语法规则 2.3 注释 2.4 关键字 2.5 标识符 2.6 常量 2.7 字符串常量 2.8 操作标点符号 2.9 操作符的优先级结合性 2.10 增值操作减值操作符 2.11 赋值操作符 2.12 例子:计算2的乘方 2.13 c系统 2.13.1 预处理器 2.13.2 标准函数库 2.14 总结 2.15 练习 第3章 基本数据类型 3.1 声明、表达式赋值 3.2 基本数据类型 3.3 字符char数据类型 3.4 int数据类型 3.5 整数类型short、longunsigned 3.6 浮点类型 3.7 typedef的用法 3.8 sizeof操作符 3.9 使用getchar()putchar() 3.10 数学函数 3.10.1 使用abs()fabs() 3.10.2 unix数学函数库 3.11 隐式类型转换强制类型转换 3.11.1 整型提升 3.11.2 寻常算术转换 3.11.3 强制类型转换 3.12 十六进制八进制常量 3.13 总结 3.14 练习 第4章 控制流 4.1 关系操作符、相等操作逻辑操作符 4.2 关系操作表达式 4.3 相等操作表达式 4.4 逻辑操作表达式 4.5 复合语句 4.6 表达式空语句 4.7 ifif-else语句 4.8 while语句 4.9 for语句 4.10 例子:布尔变量 4.11 逗号操作符 4.12 do语句 4.13 例子:斐波那契数 4.14 goto语句 4.15 breakcontinue语句 4.16 switch语句 4.17 条件操作符 4.18 总结 4.19 练习 第5章 函数 5.1 函数定义 5.2 return语句 5.3 函数原型 5.4 例子:创建乘方表 5.5 从编译器的角度观察函数原型 5.6 函数定义顺序的另一种风格 5.7 函数调用传值调用 5.8 开发大型程序 5.9 使用断言 5.10 作用域规则 5.10.1 平行嵌套代码块 5.10.2 以调试为目的使用代码块 5.11 存储类型 5.11.1 auto存储类型 5.11.2 extern存储类型 5.11.3 register存储类型 5.11.4 static存储类型 5.12 静态外部变量 5.13 默认初始化 5.14 递归 5.15 例子:汉诺塔 5.16 总结 5.17 练习 第6章 数组、指针字符串 6.1 一维数组 6.1.1 初始化 6.1.2 下标 6.2 指针 6.3 传引用调用 6.4 数组指针之间的关系 6.5 指针运算元素的大小 6.6 数组作为函数的实参 6.7 例子:冒泡排序 6.8 用calloc()malloc()进行动态内存分配 6.9 例子:归并归并排序 6.10 字符串 6.11 标准函数库中的字符串处理函数 6.12 多维数组 6.12.1 二维数组 6.12.2 存储映射函数 6.12.3 形式参数声明 6.12.4 三维数组 6.12.5 初始化 6.12.6 使用typedef 6.13 指针数组 6.14 main()函数的参数 6.15 规则数组 6.16 函数作为参数 6.17 例子:使用二分法寻找函数的根 6.18 函数指针数组 6.19 类型限定符constvolatile 6.20 总结 6.21 练习 第7章 位操作枚举类型 7.1 位操作表达式 7.1.1 按位求反 7.1.2 补码 7.1.3 位逻辑操作符 7.1.4 左移位右移位操作符 7.2 掩码 7.3 软件工具:打印int值的二进制形式 7.4 包装解包 7.5 枚举类型 7.6 例子:“石头、剪刀、布”游戏 7.7 总结 7.8 练习 第8章 预处理器 8.1 #include的使用 8.2 使用#define 8.3 带参数的宏 8.4 stddef.h中的类型定义宏 8.5 例子:用qsort()进行排序 8.6 例子:带参数的宏 8.7 stdio.hctype.h中的宏 8.8 条件编译 8.9 预定义的宏 8.10 “#”“##”操作符 8.11 assert()宏 8.12 使用#error#pragma 8.13 行号 8.14 对应的函数 8.15 例子:快速排序 8.16 总结 8.17 练习 第9章 结构联合 9.1 结构 9.2 访问结构成员 9.3 操作符的优先级结合性的总结 9.4 在函数中使用结构 9.5 结构的初始化 9.6 例子:玩扑克牌 9.7 联合 9.8 位字段 9.9 例子:访问字节 9.10 adt堆栈 9.11 总结 9.12 练习 第10章 结构列表处理 10.1 自引用的结构 10.2 线性链表 10.3 链表操作 10.4 一些链表处理函数 10.4.1 插入 10.4.2 删除 10.5 堆栈 10.6 例子:波兰记法堆栈求值 10.7 队列 10.8 二叉树 10.8.1 二叉树的遍历 10.8.2 创建树 10.9 普通的树 10.9.1 遍历 10.9.2 calloc()的用法以及树的创建 10.10 总结 10.11 练习 第11章 输入/输出操作系统 11.1 输出函数printf() 11.2 输入函数scanf() 11.3 fprintf()、fscanf()、sprintf() sscanf()函数 11.4 fopen()fclose()函数 11.5 例子:对文件进行空间加倍 11.6 使用临时文件优雅函数 11.7 随机访问文件 11.8 文件描述符输入/输出 11.9 文件访问权限 11.10 在c程序内部执行命令 11.11 在c程序内部使用管道 11.12 环境变量 11.13 c编译器 11.14 使用性能评估程序 11.15 函数库 11.16 对c代码进行计时 11.17 使用make 11.18 使用touch 11.19 其他有用的工具 11.20 总结 11.21 练习 第12章 高级应用 12.1 用fork()创建并发进程 12.2 进程的叠加:exec...()函数族系 12.3 使用pipe()实现进程间的通信 12.4 信号 12.5 例子:哲学家用餐问题 12.6 矩阵的动态分配 12.6.1 为什么二维数组无法满足要求 12.6.2 用指针数组创建矩阵 12.6.3 调整下标范围 12.6.4 一次分配所有内存 12.7 返回状态 12.8 总结 12.9 练习 第13章 从c到c++ 13.1 输出 13.2 输入 13.3 函数 13.4 类抽象数据类型 13.5 重载 13.6 构造函数析构函数 13.7 面向对象编程继承 13.8 多态 13.9 模板 13.10 c++的异常 13.11 面向对象编程的优点 13.12 总结 13.13 练习 第14章 从c到java 14.1 输出 14.2 变量类型 14.3 类抽象数据类型 14.4 重载 14.5 类的创建销毁 14.6 面向对象编程继承 14.7 多态重写方法 14.8 applet 14.9 java的异常 14.10 javaoop的优势 14.11 总结 14.12 练习 附录a 标准函数库 附录b c的语法 附录c ansi c与传统c的比较 附录d ascii字符码 附录e 操作符的优先级结合性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值