1. 三字母词

三字母词即用三个字符合起来表示另一个字符,它可以使C环境在某些缺少一些必需字符的字符集上实现。

??( [    ??< {    ??= #
??) ] ??> } ??/ \
??! | ??' ^ ??- ~

2. 转义字符

\ddd  表示由八进制数ddd的数值所代表的字符
\xddd 表示由十六进制数ddd的数值所代表的字符

3. 字面值前/后缀

(1) 在多字节字符常量前面添加L,则它是宽字符常量。如:L'X', L'e^'等。

(2) 在整数字面值后面添加L或l,可以使这个整数被解释为long型;添加U或u则用于把数值指定为unsigned型;两者均添加则被解释为unsigned long型。

4. 当for/while循环体无事可做时,单独用一行来表示一条空语句是个比较好的做法,这样清晰地表明循环体是空的,不至于使人误会接下来的一条语句才是循环体。

while ((ch = getchar()) != EOF && ch != '\n')
; // 单独用一行来表示空语句是种好做法。

5. 如果你可以互换地使用指针表达式和下标表达式时,应该使用哪一个?从可读性上看,下标显然更好;从效率上看,下标绝不会比指针更有效率,但指针有时会比下标更有效率。

// use array's index
int arr[], i;
for (i = ; i < ; ++i)
arr[i] = ; // 每次循环时都要计算i * 4 // use pointer
int arr[], *ptr;
for (ptr = arr; ptr < arr + ; ++ptr) // 只需在编译时计算一次1*4,运行时不执行乘法
*ptr = ;

6. 字符串查找

char *strchr(char const *str, int ch);  // 寻找字符ch第一次出现的位置
char *strrchr(char const *str, int ch); // 寻找字符ch最后一次出现的位置
char *strpbrk(char const *str, char const *group); // 寻找一组字符中的任意一个第一次出现的位置
char *strstr(char const *s1, char const *s2); // 寻找子字符串s2第一次出现的位置
size_t strspn(char const *str, char const *group); // 寻找字符串前缀
size_t strcspn(char const *str, char const *group ); // 寻找非字符串前缀
char *strtok(char *str, char const *sep); // 分隔并提取字符串

7. 字符分类

isspace(char ch); // 空白字符:' ', '\f', '\n','\r', '\t', '\v'
isxdigit(ch); // 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
isalpha(ch); // 字母
isalnum(ch); // 字母或数字
ispunct(ch); // 标点符号,任何不属于数字或字母的可打印符号

8. 内存操作

void *memcpy(void *dst, void const *src, size_t len);
void *memmove(void *dst, void const *src, size_t len);
void *memcmp(void const *a, void const *b, size_t len);
void *memchr(void const *a, int ch, size_t len);
void *memset(void *a, int ch, size_t len);

9. 位域(bit field)

(1) 优点:节省存储空间;可以很方便地访问一个整型值的部分内容。

(2) 缺点:可移植性较弱:(a) int位域被当作有符号数还是无符号数,不能确定;(b) 位域中位的最大数目不确定。许多编译器把位域成员的长度限制在MAX_INT内,但32位的机器和16位的机器的MAX_INT值不同。(c) 当一个声明指定了两个位域,且第2个位域比较大以致无法容纳于第1个位域剩余的位时,编译器有可能把第2个位域放在内存的下1个字,也可能直接放在第1个位域后面,从而在两个内存位置的边界上形成重叠。

10. 动态分配内存

只释放一块动态分配的内存的一部分是不允许的,动态分配的内存必须整块一起释放。如果要缩小一块动态分配的内存,应该使用realloc。

pi = (int *)malloc( * sizeof(int));
...
free(pi + ); // error! you can't free only part of the memory.

11. 函数指针的应用

(1) 回调函数。用户把一个函数指针作为参数传递给其他函数,后者将“回调”用户的函数。当你编写的函数必须能够在不同的时刻执行不同类型的工作或执行职能由函数调用者定义的工作时,你都可以使用这个技巧(此时往往需要把参数类型声明为void *)。许多窗口系统使用回调函数连接多个动作,如拖拽鼠标和点击按钮来指定用户程序中的某个特定函数。

(2) 转移表。适用于对不同的输入调用不同的函数的场合。

// 袖珍式计算器
double add(double, double);
double sub(double, double);
double mul(double, double);
double div(double, double);
...
double (*oper_func[])(double, double) = {add, sub, mul, div, ...};
result = oper_func[oper](op1, op2);

12. 字符串常量

当一个字符串常量出现在表达式中,它的值是个指针常量。编译器把这些指定字符的一份拷贝存储在内存的某个位置,并存储一个指向第一个字符的指针。因此,类似数组名,我们可以对字符串常量进行下标引用、间接访问以及指针运算。

"xyz" + ; // 结果为一个指针,指向字符'y'
*"xyz"; // 结果为字符'x'
"xyz"[]; // 结果为字符'z'
printf("%s\n", "**********" + - n); // 打印n个星号*,注意0 <= n <= 10

13. 预定义符号

14. 宏和函数的区别

15. 输入/输出函数

(1) 错误报告

void perrno(char const *message);  // <stdio.h>

(2) 终止执行

注意exit与return不同,return是退出当前函数,exit是退出整个程序。

void exit(int status);  // <stdlib.h>

(3) I/O总览

(4) 文件流

FILE *fopen(char const *name, char const *mode);  // 打开文件,失败时返回NULL
int fclose(FILE *f); // 关闭文件,成功时返回0,失败时返回非零值

(5) 字符I/O

// 读入字符
int fgetc(FILE *stream); // 函数
int getc(FILE *stream); // 函数或宏
int getchar(); // 从标准流stdin中读入字符 // 输出字符
int fputc(int c, FILE *stream); // 函数
int putc(int c, FILE *stream); // 函数或宏
int putchar(int c); // 向标准流stdout输出字符 // 撤销字符
int ungetc(int c, FILE *stream); // 把一个先前读入的字符返回到流中

(6) 行I/O

// 输入字符串
char *fgets(char *buf, int buf_size, FILE *stream);
char *gets(char *buf); // 从标准输入流stdio中读入字符串 // 输出字符串
int fputs(char const *buf, FILE *stream);
int puts(char const *buf); // 向标准输出流stdout输出字符串

(7) 格式化的行I/O

// 格式化输入
int scanf(char const *format, ...); // 从标准输入流stdio中读入
int sscanf(char const *str, char const *format, ...); // 从字符串str中读入
int fscanf(FILE *stream, char const *format, ...); // 从文件流stream中读入 // 格式化输出
int printf(FILE *stream, char const *format, ...); // 输出到标准输出流stdout
int sprintf(char *buf, char const *format, ...); // 输出到字符串buf
int fprintf(FILE *stream, char const *format, ...); // 输出到输出流stream

(8) 刷新和定位函数

int fflush(FILE *stream); //刷新文件流,清空缓冲区。
long ftell(FILE *stream); // 返回流的当前位置
int fseek(FILE *stream, long offset, int from); // 定位流的位置

(9) 改变缓冲方式

void setbuf(FILE *stream, char *buf); //设置数组buf,用来对流进行缓存
int setvbuf(FILE *stream, char *buf, int mode, size_t size); // mode用来指定缓冲的类型(完全缓冲、行缓冲、不缓冲)

(10) 流错误函数

int feof(FILE *stream); // 流处于文件尾时返回真
int ferror(FILE *stream); // 出现读写错误时返回真
void clearerr(FILE *stream); // 重置流的错误标志

(11) 文件操纵函数

int remove(char const *filename); // 删除文件
int rename(char const *oldname, char const *newname); // 重命名文件

16. 运行时环境

(1) 堆栈帧。函数存储变量和其他值的地方。

(2) 一个函数分成三个部分:函数序(prologue),函数体(body),函数跋(epilogue)三部分。函数序用于执行函数启动需要的一些工作,例如为局部变量保留堆栈中的内存。函数跋用于在函数即将返回之前清理堆栈。

《C和指针》读书笔记的更多相关文章

  1. csapp读书笔记-并发编程

    这是基础,理解不能有偏差 如果线程/进程的逻辑控制流在时间上重叠,那么就是并发的.我们可以将并发看成是一种os内核用来运行多个应用程序的实例,但是并发不仅在内核,在应用程序中的角色也很重要. 在应用级 ...

  2. CSAPP 读书笔记 - 2.31练习题

    根据等式(2-14) 假如w = 4 数值范围在-8 ~ 7之间 2^w = 16 x = 5, y = 4的情况下面 x + y = 9 >=2 ^(w-1)  属于第一种情况 sum = x ...

  3. CSAPP读书笔记--第八章 异常控制流

    第八章 异常控制流 2017-11-14 概述 控制转移序列叫做控制流.目前为止,我们学过两种改变控制流的方式: 1)跳转和分支: 2)调用和返回. 但是上面的方法只能控制程序本身,发生以下系统状态的 ...

  4. CSAPP 并发编程读书笔记

    CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...

  5. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  6. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  7. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  8. C#温故知新:《C#图解教程》读书笔记系列

    一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...

  9. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  10. Web高级征程:《大型网站技术架构》读书笔记系列

    一.此书到底何方神圣? <大型网站技术架构:核心原理与案例分析>通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计 ...

随机推荐

  1. Mac工具库

    1.文件传输工具 CyberDuck 2.解压缩工具 The Unarchiver 3. 录屏工具 LICEcap 4. 命令框工具 Go2Shell / iTerm 5. 提醒事项 OmniFocu ...

  2. 富文本编辑器粘贴word内容

    很多时候我们用一些管理系统的时候,发布新闻.公告等文字类信息时,希望能很快的将word里面的内容直接粘贴到富文本编辑器里面,然后发布出来.减少排版复杂的工作量. 下面是借用百度doc 来快速实现这个w ...

  3. 51nod 1503

    动态规划 $f[a][b][c][d]$ 表示从 $(1, 1)$ 走到 $(a, b)$ 和从 $(n, m)$ 走到 $(c, d)$ 的方案数 $f[a][b][c][d]$ $= f[a][b ...

  4. Irrlicht引擎剖析一

    代码风格:  1.接口以I开头,实现以C开头,保存数据的结构体以S开头  2.函数名以小写字母开头,变量以大字母开头  3.接口的公共函数,其参数大部分给了默认值  4.采用名字空间    名字空间i ...

  5. js面向对象入门

    通常我们写js以及调用: function init(){ console.log("init") } function load(){ console.log("loa ...

  6. 走进JavaWeb技术世界开篇:JavaWeb技术汇总

    微信公众号[Java技术江湖]一位阿里 Java 工程师的技术小站.(关注公众号后回复”Java“即可领取 Java基础.进阶.项目和架构师等免费学习资料,更有数据库.分布式.微服务等热门技术学习视频 ...

  7. CISCO实验记录六:EIGRP路由协议

    一.要求 1.查看当前路由协议 2.清空路由设置 3.使用EIGRP协议创建路由 4.查看EIGRP的邻居表 5.关闭自动汇总 6.使用手工汇总 二.实现 1.查看当前路由协议 #show ip pr ...

  8. Python 自学笔记(二)

    3-1.条件判断 3-1.条件判断 3-1-1.单项判断 if 3-1-2.双向判断 if...else... 3-1-3.多向判断 if...elif...else 3-2.if嵌套 4.输入 4- ...

  9. 慎用array_filter函数

    array_filter (PHP 4 >= 4.0.6, PHP 5, PHP 7) array_filter - 用回调函数过滤数组中的单元 说明 array array_filter (  ...

  10. Invoke-customs are only supported starting with Android O (--min-api 26) Message{kind=ERROR,……

    https://www.jianshu.com/p/434928537a90 在我使用构建版本gradle 26但是在将buildtoolsversion更改为27之后,就像这个图像     错误:e ...