C|C语言程序设计第二版学习笔记

一、基本概念 1、字符输入输出 一次读写一个字符putchar、getchar

void main() { int c; while ((c = getchar()) != EOF) { putchar(c); } }

注意的点(c = getchar()) != EOF-------运算符的优先级问题 (c = getchar()) != EOF与c = getchar() != EOF的区别
由于不等运算符的优先级高于复制运算符,c = getchar() != EOF等价于c = (getchar() != EOF)所以前者的c获取的是字符值,后者的c的值只会是0或者1。

为什么不把C说名成char类型 要将文件结束符与文件中任何有效的数据区分开
在没有任何输入的情况下默认返回一个特殊值EOF ,c的大小除了存储所有字符外,还必须大到可以存储文件结束符EOF EOF默认值为-1

printf("EOF is %d\n", EOF);

实际输入过程中如何结束输入 先按enter会自动换行打印之前的输入,然后再按ctrl+z进程结束,ctrl+z表示EOF,也可以通过自定义字符结束输入,例如:
void main() { int c; while ((c = getchar()) == 'q') { putchar(c); } }

2、外部变量与作用域 外部变量使用场景
假设某个工程是由两个源文件1.cpp、2.cpp链接而成,某个函数或者全局变量定义在1.cpp,而2.cpp不能用,虽然可见),要想在2.cpp用,必须在2.cpp加上extern int i,extern int sum(int a, int b); 注意声明和定义的区别
int a ; //定义一个全局变量a,是要标记存储空间的 extern int a ; //声明一个全局变量aint a = 3; //定义一个全局变量并初始化为3,标记存储空间 extern int a = 3; //定义一个全局变量并初始化为3

变量作用域/生存周期
C|C语言程序设计第二版学习笔记
文章图片

int global = 9; static int i = 5; void test() { int m = 3; i = 10; }

静态存储区相对固定,用于存放全局变量和静态变量,内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量, static 变量
局部变量 局部作用域,局部变量m存放在栈中,当test函数结束,m将被销毁。
全局变量 global为全局变量,作用域为当前文件,生存周期为整个程序执行周期,在进程销毁时销毁。
静态变量 i为静态全局变量,作用域为当前文件,i在进程销毁时销毁。以test接口举例,虽然已经给i重新赋值,但是下次调用该接口时i的值还是5。
二、数据类型、运算符 1、数据类型
C|C语言程序设计第二版学习笔记
文章图片

C|C语言程序设计第二版学习笔记
文章图片

隐式数据类型转换规则 C在以下四种情况下会进行隐式转换
算术运算式中,低类型能够转换为高类型。 赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他。 函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。 函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。

算数运算中默认的隐式转换规则 【C|C语言程序设计第二版学习笔记】{char, uchar, short, ushort}->int-> uint->long->ulong->float->double
2、运算符
运算符优先级 优先级最高()、[] 、->、.,结合性从左至右 单目运算符: 负号运算符-、按位取反运算符~、自增/减运算符++/–、取值运算符*(对指针变量操作)、取地址运算符(&变量/函 数名)、逻辑非运算符(!表达式)、类型强转、sizeof(长度运算符),结合性从右至左
双目运算符:/ 、* 、 % 、 +、 -、 << 、 >> 比较运算符:> 、 >= 、 < 、 <= 、 == 、 != 位运算符: & 、 ^ 、 | 逻辑运算符: &&、 || 三目运算符:?:
表达式1 ? 表达式2 : 表达式3

赋值运算符:= 、 /= 、 *= 、%= 、+= 、-= 、<<= 、>>=、&=、^=、|= 逗号运算符 3、位运算
常见应用场景 判断数字的奇偶性
if(n & 1 == 1){//(n&1 == 0)则n是偶数 return 1; }

交换两个数
void swap(int x, int y) { #if 0 int temp = x; x = y; y = temp; #endif x ^= y; y ^= x; x ^= y; }

找出数组中唯一一个不重复的数 一个数字和0异或是它本身,和它本身异或是0
int find(int[] arr, int len){ int tmp = arr[0]; for(int i = 1; i < len; i++){ tmp ^= arr[i]; } return tmp; }

求m的n次方
long long res = 1; while(n) { res * = m; n &= (n - 1); }

乘除运算 位的拼接多用| 三、控制流 1、if-else组合 几种常见类型变量与“零值”进行比较
bool变量与“零值”进行比较
bool bTestFlag = FALSE; if(bTestFlag); if(!bTestFlag);

指针变量与“零值”进行比较
int * p = NULL; if(NULL == p); if(NULL != p);

float变量与“零值”进行比较
const float EPSINON = 0.00001; float fTestVal = 0.0; if((fTestVal >= -EPSINON) && (fTestVal <= EPSINON));

2、switch、case组合 if、else 一般表示两个分支或是嵌套表示少量的分支,但如果分支很多的话……还是用 switch、case 组合
case 后面只能是整型或字符型的常量或常量表达式 case 语句的排列顺序(规则) 按字母或数字顺序排列各条 case 语句、把正常情况放在前面,而把异常情况放在后面、按执行频率排列 case 语句、default 子句只用于检查真正的默认情况
3、do、while、for关键字 break与continue的区别
break终止循环:for、do-while、while-do、switch continue结束本次、进入下一次循环:for、do-while、while-do 四、指针与数组 1、&运算符 只能用于内存中的对象,变量和数组元素;不能用于常量、表达式、寄存器变量
2、*运算符 间接寻址或者间接引用运算符,作用于指针时访问指针所指向的对象,*ptr的值为11
int value[10] = {11, 333}; int *ptr = &value[0];

现在将*ptr的值增加1
*ptr += 1; 等同于 (*ptr)++; //()是为了先取值后加1 等同于 ++*ptr; /*因为一元运算符++ 和 * 的结合律是从右至左*、

3、指针的算术运算规则 间
4、字符数组与字符串常 量 间

    推荐阅读