C语言程序设计:现代方法阅读笔记
第二十六章
- atexit函数允许用户“注册”在程序终止时要调用的函数:atexit(func); 在程序终止后,func函数会被自动调用
- clock()函数可以计算程序运行时间
- time函数返回当前的日历时间,返回类型是time_t
第二十四章
- void assert(expression); 如果返回非0,则正常运行,如果返回0,则会向stderr返回一条消息,并且调用abort函数终止程序
- 用多了影响程序的运行时间
- #define NDEBUG 禁用assert
- errno用来检测库函数调用中的错误,如果发生了错误,errno返回非0,但是注意在函数调用前将errno置零
- perror和strerror输出errno的错误具体信息
- signal(SIGINT, handler); handler为信号处理函数
- raise触发信号函数
- setjmp设置跳转标志位的位置,longjmp函数跳转到设定位置处。与goto语句不同的是,可以实现函数之间的跳转。标志位类型为jmp_buf
- 为什么p451 tsignal.c的输出有多种
第二十三章
- <math.h>的cbrt函数计算参数的立方根
- <ctype.h>是字符处理库,判断是否是数字,是否大写等
第二十二章
- 输入重定向: demo <in.dat 输出重定向: demo > out.dat
- 使用fopen函数时要检测其返回值是不是空指针
- fopen打开二进制文件是,需要在模式字符串中包含字母b
- freopen可以实现重定向
- sprintf()函数将输出写入字符数组中,可以用来把数转换成字符格式
- SEEK_CUR,文件的当前位置怎么确定
第二十一章
- ptrdiff_t 当进行指针相减运算时,其结果的类型,这个必须时有符号整型
- <stddef.h>中的offsetof函数可以计算结构体的起点到指定成员间的字节数,即偏移字节量
- 结构体的第一个成员的地址与结构体自身的地址相同
- 两个指向整型的指针相加减的返回值,如果用的这个值的话需不需要强制转换
第二十章
- i«j的值是将i中的位左移j位后的结果。每次从i的最左端溢出一位,在i的最右端补一个0位
- i»j的值是将i中的位右移j位后的结果,如果i是无符号数或非负值,则需要在i的左端补0.如果i是负值,一些情况左端补0,一些情况保留符号位补1
- 设置i的第4位:i|=0x0010; 设置第j位: i|=1«j;
- 清除i的第4位:i&=~0010; 清除第j位:i&=~(i«j);
- 测试i的第4位:if(i&0x0010); 测试第j位:if(i&1«j);
第十九章
- 将具体数据实现方式隐藏起来的数据类型称为抽象数据类型
- 描述了对象但缺少定义对象大小所需的信息
- p360用void*表示的数据项为什么不能是int、double之类的基本类型
第十八章
- 在函数体内部声明的变量具有自动存储期限、块作用域,并且无链接
- 在程序最外部声明的变量具有静态存储期限,文件作用域和外部链接
- 内部链接:只能被用于单独一个文件,并且被函数共享;外部链接:可以被程序中的几个文件共享
- register 由于寄存器没有地址,所以对寄存器变量使用&取址是非法的
- 指针数组:int *p[10]; 数组指针int (*p)[10];
- 返回指针的函数:int *f(int a); 函数指针 int (*p)(int a);
- 具有静态存储期限的变量的初始化式必须是常量
- const不能用于常量表达式
- 内联函数与define定义的区别
第十七章
- 内存分配函数malloc, calloc, realloc的返回类型为 void*
- 若p为指向结构体的指针,利用scanf时,scanf(”%d”, &p→value); 必须加&,如果没有&,则传入的是value的值
- 受限指针:int *restrict p; 如果指针p指向的对象在之后需要修改,那么该对象不会允许通过除指针p之外的任何方式访问
- NULL的定义:#define NULL (void *) 0
- 受限指针的应用
- qsort()
第十六章
- 两个结构体之间可以直接赋值:struct1 = struct 2; 但是不能进行其他操作,例如判断==或者!=
- 声明了struct part {…}; 后面必须加分号,如果想声明结构体变量,则struct part part1; 不能省略struct字段
- typedef struct {…} part; 进行了类型声明,之后可以直接 part part1;来声明结构体变量
- 结构变量存储在不同的内存地址中,而联合变量的成员存储在同一内存地址中
- 如果把一个值存入联合体u的u.d中,那么先前存储在u.i的值将会丢失
- 枚举类型的存储方式
第十五章
- extern int i; extern表示变量i是在程序中的其他位置定义的,而不是在这个位置
- 在数组的声明中使用extern时,可以省略数组的长度。extern int a[]; 因为此刻编译器不需要为数组a分配空间
- #ifndef 头文件名 #define 头文件名 #endif
- makefile的使用方法需要熟悉
第十四章
- 预处理器将每一行的注释都替换为一个空格字符
- #运算符将宏的一个参数转换为字符串字面量
- ##运算符可以将两个记号“粘合”在一起
- 宏定义的作用范围通常到出现这个宏的文件末尾
- #indef和#ifndef 测试标识符是否没有被定义为宏
- p231如果宏循环替换会怎么样。答:如果在扩展宏的过程中原先宏名重复出现的话,宏名不会再次被替换
第十三章
- char ch; ch = “abc”[1]; 返回ch = b,在字符串后面加下标为取字符串的对应字符
- 当声明用于存放字符串的字符数组时,要始终保证数组的长度比字符串的长度多一个字符
- 当指针指向字符串时,不能用指针修改字符串的内容:char *p = “abc”; *p = 'b';
- char a[] = “hello”; a有6个字节空间
- scanf(”%s\n”, str); 不用再str前加&
- scanf会在开始跳过空白字符,并且在遇到空白字符后停止输入,而gets函数不会
- if(str1 == str2) 那两个字符串作为指针来比较,因为他们都有不同的地址,所以比较结果一定为0
- while (*s) s++; 和 while(*s++); 搜索字符串结尾的空字符
- argc是命令行参数的数量,argv是指向命令行参数的指针数组,argv[0]指向程序名,从argv[1]到arfv[argc-1]指向余下的命令行参数,argv[argc]始终是一个空指针
- 根据getchar()返回是否为EOF来检测读入字符是否失败
- p205 如果输入的字符个数正好为n,那么会不会存储空白字符
第十二章
- p = &a[5]; q = &a[1]; i = p - q;(i=4) i = q - p;(i=-4)这里的计算不用考虑数组元素字节的大小
- int *p = (int []){3, 0, 3, 4, 1}; 指向复合常量的指针
- 对数组元素个数为N的数组a[N]取地址运算符是合理的
- *(p++)的值是*p,即p当前指向的对象,之后再自增p,等同于*p++;(*p)++返回的是p指向的对象的值,之后在自增对象
- *++p或*(++p) 先自增p,自增后表达式的值是*p;++*p或++(*p) 先自增*p,自增后表达式的值是*p
- 可以同数组的名字作为指向数组第一个元素的指针,但是不能给数组名赋新的值。例如: while(*a != 0) a++;
- int *p; p = a[i]; 访问二维数组第i行。int (*p)[N]表示数组指针,(*p)[i]中,*p代表a的一整行,(*p)[i]选中了该行的第i列的元素
- 如果p的类型是int *,那么p+j表示给p加上4j,因为int的类型需要4个字节存储
- p192页处理多维数组的列的代码中 p = &a[0];能不能改成 p = a;
第十一章
- 指针就是地址,而指针变量就是存储地址的变量。如果*p是指针,那么*p表示p当前指向的对象。
- j = *&i 等价于 j = i
- int *p, *q; p = q表示把q的内容(即q指向的变量的地址)复制给p; *p = *q表示把q指向的值(q指向的变量的值)复制到p指向的对象
- int i, *p; p = &i; scanf(”%d”, p); p前不需要加&
- 指针作为返回值时,不能返回函数内一个局部变量的地址,因为函数结束后局部变量被释放
- 针对(3),如果 int *p, *q, i=3; *p = &i; *q = *p 是否合法
第十章
- 函数体中的静态存储变量具有永久的存储单元,一个函数中的静态存储变量对其他函数不可见,只为所在函数的再次调用保留变量值
- 如果声明了外部静态全局变量i,在某函数内也声明静态变量i,是否冲突
第九章
- 如果省略返回类型,C89标准会假定函数返回值的类型是int类型,但这在C99中这是不合法的
- printf函数返回显示的字符个数
- 当形式参数是一维数组时,可以不说明数组的长度
- 在把数组名传递给函数时,不要在数组名的后面放置方括号
- 函数无法检测传入的数组长度的正确性
- 声明多维数组时,只能忽略第一维的长度,必须声明列的数量
- 声明函数 int func(int n, int a[星号]); 星号表示数组a的长度与形式参数列表中前面的参数(即n)相关
- int func(int a[static 3], int n); 表明数组a的长度至少是3。如果数组参数是多维的,static仅可以用于第一维(即行)
- 在函数调用f(a, b)中,逗号是标点符号;而在f1)中,逗号是运算符
- 函数原型中的形式参数的名字不需要和后面函数定义中给出的名字匹配
- 复合字面量: total = sum_array((int []){3, 0, 3, 4, 1},5);
- printf中返回的字符个数,那么转移字符例如”\n”是算一个字符还是两个字符
- static在描述数组长度中的具体作用
第八章
- a[i] = b[i++];可能导致未定义的行为,不建议这样写
- int a[5]={[2]=1, [4]=7}; 结果是a[5]={0,0,1,0,7};
- int c[10]={5,1,9,[4]=3};前三个元素为519,元素4的值为3,其余元素默认为0
- sizeof(a)/sizeof(a[0]),计算数组长度,但是会有警告,因为sizeof返回size_t类型,需要强制转换
- C99标准中引入变长数组; int n; int a[n]; goto语句不能绕过变长数组的声明,这样会导致程序对未分配空间的数组进行访问
- int a[] = {1,5,9,[0]=2,7}; 结果a[3]={2,7,9};
- 在二维数组a[3][3]中,直接操作a[0]=1的结果
第七章
- 查看头文件<limits.h>可以确定整数类型范围
- 在整数后加L表示长整型,15L;在整数后加U,表示无符号整型,15U;LU也可以结合,15UL,表示既是长整型又是无符号的
- 两个int型整数相加的结果必须是int型
- 读写短整数时,在d、o、u、x前面加上h
- 默认情况下,浮点常量都以双精度数的形式存储
- touppper函数可以检测大小写,如果是小写则转换成对应的大写,如果是大写则返回原值。该函数在<ctype.h>中
- getchar()返回一个int型变量
- 类型转换原则为向上转型,signed类型优先转换为unsigned
- float f; f = 15.33f; 这里如果15.33后面不加f,15.33将是double类型
- long i; int j = 1000; i = j * j; 在类型转换之前的j * j发生了溢出,需要改成 i = (long)j * j;如果改成i = (long)(j * j)是错误的,因为在强制转换前就发生了溢出
- sizeof()函数的返回类型是size_t,为无符号整型
- printf函数中输出一个double型浮点数,应该用f而不是lf,printf函数不接受lf类型
- ” %c”在%前空一个空格可以是scanf函数读入下一个非空白字符
- long int + unsigned int的结果为什么类型(书中好像存在错误P101,P102)
第六章
- do while循环在while的判断值为真是继续进入循环,为假时跳出循环
- for(int i = 0; i > 0; i++); 如果变量i在之前已经做了声明,这个语句将创建一个新的i且该值仅用于循环内
- 逗号表达式:表达式1, 表达式2; 计算表达式1并且扔掉计算的值,之后计算表达式2,把这个值作为整个表达式的值
- 带空循环体的循环更便于读取字符数据
- for循环里声明多个不同类型的变量的结果
- ++i, i+j; 执行后i的值为多少,如果输入i=1,j=5,i在表达式结束后是否为2
第五章
- i < j < k 等同于 (i < j)< k;
- &&和|| 在左边操作数的值推导出来之后会考虑要不要推导右操作数的值,而&和|会把两边都推导
- i > 0 && ++j > 0; 如果i < 0,则不会执行后面的j自增
- 布尔值的三种替换方法:标志位flag;宏定义TRUE为1和FALSE为0;宏定义BOOL 为int;
- C99标准中定义了 _BOOL类型,同时可以引用<stdbool.h>,这样可以直接用 bool 来声明布尔类型
- 选择语句case后面必须是常量表达式,且后面可以跟任意数量的语句
- 如果没有break,控制将会从一个分支继续到下一个分支,将之后的分支语句全部执行,直到遇到break或者switch执行完
- 如果i是int型,f是float型,条件表达式(i > 0 ? i : f)的结果是float型,即使 i > 0 为真
- 条件表达式冒号的左右两边可不可以写多个表达式
第四章
- N元运算符表示该运算符需要N个操作数
- 当两个操作数都是整数时,运算符/会丢掉分数部分,例如1/2的结果为0而不是0.5
- 如果%的操作数有一个不是整数,则程序无法编译通过
- 在C99标准中,除法的结果向零取整,例如-3/2的结果为-1;并且i%j的结果的符号与i相同
- 一元运算符(+和-)是右结合的, - + i实际是-(+ i)
- int i; float f; f = i = 33.1f; 结果i=33,f=33.0而不是33
- e = (a + b)*(c - d);无法判断是(a+b)先求出来还是(c-d)先求出来
- v += e只求一次v的值,而v = v + e会求两次v的值
- 输入 int i + 1;的执行结果
第三章
- %m.pX转换说明:m表示显示的最少字符数,默认右对齐;p表示显示的小数位数,默认6位;X为具体的转换说明符
- 如果要左对齐,则在m前加“-”。p如果对整数使用,不会显示小数,而是在整数多出来的位数前补0
- 编写程序时无法预知数的大小或者变化范围很大的情况下,可以用“g”说明转换符
- 尽量避免使用scanf函数,可以采用字符格式读取所有数据,然后把他们转换成数值形式
- 在scanf格式中,%d只能匹配十进制数,而%i可以匹配八进制、十进制和十六进制
- 在printf中“%%”显示百分号%
- 在scanf中如果要求输入一个数,但是输入了别的字符,则会跳过对应匹配,只能匹配到数值
- 在scanf转换说明中输入“\n”是什么结果
- 如果scanf输入的是%c,是不是就会考虑空格,另外如果是%c%c,sacnf如何如何判断输入
第二章
- 进行算术运算时float比int慢,并且float所存储的数值往往只是一个近似值,可能存在误差
- 在把小数赋给一个float变量时,需要在小数后面加一个f例如:a = 33.24f,不加可能会引发编译器警告
- 计算m/n向上取整,可以(m+(n-1))/n
- int a, b, c = 1; 只有c被初始化为1,a和b都没有被初始化
- 在编写输入时,需要考虑实际输入内容的类型
- 如果int a b=0; 会发生什么情况
第一章
- 在编译C语言程序检查基本语法错误的同时,也需要关注越界问题和内存泄漏等问题
C语言程序设计:现代方法阅读笔记的更多相关文章
- 《C语言程序设计教程》学习笔记
<C语言程序设计教程>--朱鸣华.刘旭麟等 第一章 C语言概述 1.C语言的特点: 1)兼具高级.低级语言的双重能力(C语言允许直接访问物理地址,能够进行位操作,能实现汇编语言的大部分功能 ...
- C语言程序设计-现代方法(笔记1)
第一章 C语言概述 1.C语言的历史(1.1) 起源:贝尔实验室开发的UNIX操作系统的副产品.标准化:C89和C99.基于C的语言:C++,Java,C#,Perl. 2.C语言的优缺点(1.2) ...
- C语言程序设计-现代方法(笔记3)
第十三章 字符串 1.字符串字面量(13.1) 字符串字面量:用一对双引号括起来的字符序列.字符串字面量可以像字符常量一样包含转义字序列. 在字符串字面量中小心使用八进制和十六进制的转义序列. 字符串 ...
- C语言学习书籍推荐《C语言程序设计 现代方法(第2版)》下载
下载地址:点我 C语言仍然是计算机领域的通用语言之一,但现在的C语言已经和当初的时候大不相同了.本书主要的一个目的就是通过一种“现代方法”来介绍C语言,书中强调标准C,强调软件工程,不再强调“手工优化 ...
- C语言程序设计现代方法_数组(第八章)
C语言不要求检查下标的范围.当下标超出范围时,程序可能会执行不可预知的行为. 看下这个程序: #include <stdio.h> #define N 10 // int main() { ...
- C语言程序设计现代方法_基本类型(第七章)
C语言支持两种不同的数值类型,整数类型,浮点类型. C语言的整数类型有不同的尺寸.int类型通常为32位,但在老的CPU上可能是16位.有些可能是64位. 因此,int型如果在16位CPU上最大值就是 ...
- 《C语言程序设计现代方法》第4章 表达式
C语言的一个特点就是它更多地强调表达式而不是语句,表达式是表示如何计算值的公式. 当表达式包含两个或更多个相同优先级的运算符时,运算符的结合性(associativity)开始发挥作用.如果运算符是从 ...
- C语言程序设计现代方法1,2,3章
1:浮点型(float)运算比int慢,并且可能存在舍入误差 如float存储0.1,以后使用可能会变成0.099999999987 2:宏定义只用大写,这是大多数C程序猿遵循的规范! C语言区分大小 ...
- 《C语言程序设计现代方法》第4章 编程题
1 编写一个程序,要求用户输入一个两位数,然后按数位的逆序打印出这个数. 方法一:没技术含量的 #include <stdio.h> int main() { int high, low; ...
随机推荐
- laravel save() 返回 null
原因:引用其他方法时,没有 return save()的操作结果. 在使用save()方法时,发现返回值是:null:
- 小学生都能学会的python(函数的进阶)
小学生都能学会的python(函数的进阶) 1. 动态传参 形参: 1. 位置参数 2. 默认值参数 3. 动态传参 *args 动态接收位置参数 **kwargs 动态接收关键字参数 def fun ...
- 关于@SuppressWarnings("unchecked")注解
解释一: 屏蔽某些编译时的警告信息 在强制类型转换的时候编译器会给出警告 加上程序代码 @SuppressWarnings("unchecked& ...
- oauth2.0里回调地址返回code中如何让code不显示在URL里?
背景: 最近在调用对方提供的oauth2.0接口的时候,返回code在URL显示,但是会影响到本系统调用其他的菜单项的操作,所以想把返回的code值去掉. 解决办法: 想了各种解决办法,目前把 ...
- HDU 4332 Contest 4
顶好的一道题.其实,是POJ 2411的升级版.但POJ 2411我用的插头DP来做,一时没想到那道题怎么用状态DP,于是回头看POJ 2411那一道的状态DP,其实也很简单,就是每一行都设一个状态, ...
- HDU Train Problem I (STL_栈)
Problem Description As the new term comes, the Ignatius Train Station is very busy nowadays. A lot o ...
- [debug]重定义默认參数
编敲代码过程中遇到重定义默认參数的错误,例如以下例所看到的: #include<iostream> #include<stdlib.h> using namespace std ...
- POJ 1765 November Rain
题目大意: 有一些屋顶,相当于一些线段(不想交). 问每一条线段能够接到多少水,相对较低的屋顶能够接到高屋顶留下的水(如题图所看到的).因为y1!=y2,所以保证屋顶是斜的. 解题思路: 扫描线,由于 ...
- hdu1276(士兵队列训练问题) java集合水过
点击打开链接 有人说这题属于栈或者队列,个人认为说集合应该比較准确点. Problem Description 某部队进行新兵队列训练,将新兵从一開始按顺序依次编号.并排成一行横队,训练的规则例如以下 ...
- bzoj3262: 陌上花开(cdq分治+树状数组)
3262: 陌上花开 题目:传送门 题解: %%%cdq分治 很强大的一个暴力...感觉比分块高级多了 这道题目就是一个十分经典的三维偏序的例题: 一维直接暴力排序x 二维用csq维护y 三维用树状数 ...