C Primer Plus(三)
重读C Primer Plus ,查漏补缺
重读C Primer Plus,记录遗漏的、未掌握的、不清楚的知识点
文件输入/输出
1、fgets函数在读取文件内容时会将换行符读入,但gets不会,fputs函数在写入文件时不会追加一个换行符,但puts会,应该对应配合使用。
2、不同操作系统下,以文本方式打开文件,几乎没有区别,但由于不同操作系统文件结尾的的标识符不同,以二进制方式打开时,可能会将结尾标识符错误输出。
3、对于大型文件,有两个特殊的函数提供支持:
int fgetpos(FILE * restrict stream, fpos_t * restrict pos);
int fsetpos(FILE * stream, const fpos_t *pos);
其中,fpos_t是通过其他类型定义的文件定位类型,在使用上述函数时,fsetpos中的pos必须是通过fgetpos函数获得的。当两个函数执行成功时,会返回0。
4、其他标准IO函数
size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb, FILE* restrict fp);
size_t fread(void * restrict ptr, size_t size, size_t nmemb, FILE* restrict fp);
// 是否到达文件结尾
int feof(FILE* fp);
// 是否发生读写错误
int ferror(FILE* fp);
// 将字符回流进缓冲区
int ungetc(int c, FILE* fp)
// 立刻将缓冲区内容写入文件
int fflush(FILE* fp)
// 替换缓冲区
int setvbuf(FILE* restrict fp, char * restrict buf, int mode, size_t size)
当然,上述的一些函数在目前的VS Studio中会被认为是不安全的函数,已经过时。
结构和其他数据格式
5、C99标准下支持对结构体初始化时的任意字段赋值:
struct book gift = {.value=25.99, .author="Harry Potter", .title="Yoo"};
// 此时 0.25 会被赋给定义结构体时author后的那个成员,即便那个成员已经被初始化过。
struct book gift = {.value=25.99, .author="Harry Potter", 0.25};
6、对于结构体数组,数组名不是其首个元素的地址,需要引用首个元素再取地址。
7、在结构中一般使用字符数组,而不使用字符指针,结构中的字符指针无法很好的初始化地址,这样会有使用上的风险,所以结构中的字符指针最好只指向那些字符串常量或者是指向由malloc分配的内存。
8、C99标准对结构也支持复合文字,同时复合文字的结构也可以作为函数参数,也可以取地址,也和普通变量有相同的生存周期,声明方式如下:
(struct book) {"The Idiot", "Fyodor Dostoyevsky", 6.99}
9、C99支持一种伸缩型数组成员,这个成员必须是结构中最后一个成员,而且不是唯一一个成员,就像声明普通数组一样,但括号内为空,这个成员不会在声明后立即存在,实际上,C99希望使用malloc为这样含有伸缩型成员的数组分配空间。
struct flex{
int count;
double avreage;
double scores[]; // 伸缩型成员
}
struct flex * pf;
pf = malloc(sizeof(struct flex) + *sizeof(double))
pf->count = ;
pf->scores[] = 2.99;
10、对于C中的枚举类型,某些属性不能顺延至C++,例如C允许对枚举做++运算,但C++不允许。
enum spectrum {red, yellow, green, blue};
spectrum color;
for(color = red; color != blue; color++);
11、在C中,对于同一作用域下的标记和变量名可以使用同一个名字,因为对于标记(枚举、结构,联合),他们使用的名字空间与普通变量不同,但C++中不可以,例:
struct complex{double x, double y};
int complex; // 在C中不会引起冲突,但C++中则不允许
12、对于函数指针执行函数时,会出现两种语法,ANSI C把他们视为等价的。
void ToUpper(char *);
void (*pf) (char*);
char str[] = "hello";
pf = ToUpper;
(*pf)(str); // 语法1
pf(str); // 语法2
位操作
13、为什么一个字节可以表示的有符号整数的范围是-128~+127?
看这里:https://www.cnblogs.com/Dylan7/p/12649972.html
14、计算机中小数是如何表示的?(一部分表示指数,一部分表示小数,有精确度问题)
15、对位进行操作的第二种方法就是位字段(从没用过,细节可以用到时再研究),位字段好比一个结构体,但其中的成员,代表的是某几位上的值,好处是避免了通过复杂的位运算去控制某些位上的值,声明例如:
struct box
{
unsigned int opaque : // 整体结构的对齐补齐依据无符号整型
unsigned int fill_color : // 数字代表需要几位来表示这个字段
unsigned int : // 可以跳过一些位
unsigned int show_border : // 但一个字段不能横跨两个无符号整型的边界
}
struct box b;
b.fill_color = ; // 不可以超过字段所占用的位可表示的上限
C预处理器和C库
16、程序翻译的第一步,在预处理前,编译器会对代码做一些翻译,将代码中出现的字符映射到源字符集(用来处理多字节字符和使C外观更加国际化的三元字符扩展),接着查找反斜杠后紧跟换行符的实例,将其转换为一行,然后将文本划分为预处理的语言符号序列以及空白字符及注释序列(将用一个空格代替一个注释),最后进入预处理阶段,寻找每一个预处理指令。
17、 几个宏定义
#define F(x) #x // #将语言符号字符串化
#define F(x) F##x // ##将两个语言符号组成一个语言符号
#define F(x,...) printf("x", __VA_ARGS__) // ...和__VA_ARGS__,可变参数(必须为最后一个参数)
18、#if 指令后面跟常量整数表达式,可以与 #elif 配合使用,例如:
#if 1 == SYS
...
#elif 2 == SYS
...
#endif
同时,还有以下新的实现方式,defined 是一个预处理运算符,如果参数使用#define定义过,defined返回1,否则返回0。
#if defined(INMPC)
...
#elif defined(VAX)
...
#endif
19、#line 用于重置__LINE__,__FILE__宏所报告的行数
#error 指令使预处理器可以发出一条错误信息
#line 10000
#line 10 cool.c"
#if __STD_VERSION__ != 199901L
#error Not C99
#endif
20、C99 提供了_Pragma预处理器运算符,可以将字符串转换成常规的编译指示
_Pragma("c99 on") 等价于
#pragma c99 on
21、内联函数不会在调试器中显示,例如使用gdb调试时,有些内联函数无法被手动执行,同时内联函数具有内部链接属性,所以在多文件程序中,使用其他文件的内联函数时,要单独声明一次,并且在尝试获 取内联函数的地址时,编译器都会产生非内联函数,也就是说可能产生外部定义的函数。
23、在main()函数结束时,会隐式地调用exit()函数,同时,可以通过atexit()函数,向exit()注册在程序允许结束时执行的函数,ANSI C保证可以设置至少32个函数,按照先设置后执行的顺序执行,atexit()函数接受一个返回值为void,参数也为void的函数指针作为唯一参数。
24、memcpy()与memmove()两个函数的区别在于声明上,以及memcpy()会假定两个内存区没有重叠。
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
void *memmove(void *s1, void *s2, size_t n);
25、可变参数的相关内容包含在stdarg.h头文件中,使用起来比较复杂,包括初始化可变参数列表,遍历列表,清理列表,拷贝列表等一系列操作,需要时再研究。
高级数据表示
26、 这章没什么新奇内容,但它告诉我们,用C可以实现很多复杂的数据结构。
2020年4月16日,星期五,晚23点09分,首次完整读完这本书,共勉。
学如逆水行舟,不进则退;心似平原放马,易纵难收。
C Primer Plus(三)的更多相关文章
- 如何学习C++? C++ Primer第三版中文版
C++只是一门工具,要在实际项目中才能感受到它的伟大.是慢慢积累的(任何知识都是,冰冻三尺非一日之寒),它的思想是慢慢领悟的. 知道它的语法不代表你会用,你会用不代表你就会建造起高水平的作品,这是一个 ...
- C++Primer 第三章
//1.位于头文件中的代码一般不应该使用using声明.这是因为头文件的内容会拷贝到所有引用它的文件中,可能会产生始料未及的命名空间冲突. // 三种使用命名空间中的名字的方法 using names ...
- C++ Primer 第三章 标准库类型vector+迭代器iterator 运算
1.vector: 标准库类型vector表示对象的集合,其中所有对象的类型都相同,集合中的每个对象都有一个与之对应的索引,索引用于访问对象.因为vector“容纳着”其他对象,所以它也常被称作容器( ...
- C++primer第三章标准库类型
除第二章介绍的基本数据类型外,C++ 还定义了一个内容丰富的抽象数据类型标准库. 本章将介绍标准库中的 vector.string 和 bitset 类型. string 类型支持长度可变的字符串 v ...
- C++ Primer 第三章 标准库类型string运算
1. 标准库类型 string string表示可变长的字符序列,使用string必须首先包含string头文件.如何初始化类的对象是由类本身决定的. int n; string s1;//默认初始化 ...
- C++ primer第三章作业
3.1节 练习3.1: 使用恰当的using声明重做1.4.1节(第11页)和2.6.2节(第67页)的练习 #ifdef 1 #include <iostream> using std: ...
- c++primer 第三章编程练习答案
3.7.1 #include<iostream> int main() { using namespace std; ; int height,inch,foot; cout <&l ...
- c++ primer 第三章 标准库类型
1. string 标准库 1.1初始化 string s1; 默认构造函数s1为空 string s2(s1); 将s2初始化为s1的一个副本 string s3("value" ...
- <<C++ Primer>> 第三章 字符串, 向量和数组 术语表
术语表 第 3 章 字符串, 向量和数组 begin: 是 string 和 vector 的成员,返回指向第一个元素的迭代器.也是一个标准库函数,输入一个数字,返回指向该数字首元素的指针. 缓 ...
- C++ Primer 笔记 第三章
C++ Primer 第三章 标准库类型 3.1using声明 例: using namespace atd; using std::cin; 3.2string类型 初始化方式 string s1 ...
随机推荐
- slf4j、log4j、 logback关系详解和相关用法
slf4j log4j logback关系详解和相关用法 写java也有一段时间了,一直都有用slf4j log4j输出日志的习惯.但是始终都是抱着“拿来主义”的态度,复制粘贴下配置文件就开始编码了, ...
- 剑指Offer之二进制中1的个数
题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 解法1:使用Integer.toBinanryString()返回int变量的二进制表示的字符串. [在Intege ...
- python之robotframework+ride测试框架
一.robotframework简介 Robot Framework是一款python编写的功能自动化测试框架.具备良好的可扩展性,支持关键字驱动,可以同时测试多种类型的客户端或者接口,可以进行分布式 ...
- eatwhatApp开发实战(一)
开发背景: 当你想用抛硬币来决定事情的时候,那么硬币抛起的瞬间,你就有答案了.一样的,吃啥?eatwhat点开,按钮一点,你就可以知道你中午要吃啥. 话不多说,项目开发走起 ADT点开,New==&g ...
- IT笑话十则(二)
一.女程序员征婚 女程序员是这么征婚的: SELECT * FROM 男人们 WHERE 未婚=true and 同性恋=false and 有房=true and 有车=true and 条件 in ...
- PYTHON 黑帽子第二章总结
基于python3编写 import sys, socket, getopt, threading, argparse, subprocess # globals options listen = F ...
- hexo搭建个人网站及hexo+nginx部署个人网站
先放个配置好了 server { # 监听端口 listen ; # 监听ip 换成服务器公网IP server_name mr-lin.site; location / { root /web/my ...
- Rocket - debug - Example: Triggers
https://mp.weixin.qq.com/s/zPNyrBOhsytkRrZTDTEvpw 介绍riscv-debug的使用实例:配置Triggers功能. 1. Trigger Trigge ...
- HTML中块级行级元素小分类
行内元素列表: <a>标签可定义锚 <abbr>表示一个缩写形式 <acronym>定义只取首字母缩写 <b>字体加粗 <bdo>可覆盖默认 ...
- Java实现 LeetCode 647 回文子串(暴力)
647. 回文子串 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串. 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串. 示例 1: 输入: "a ...