目录
1、计算机结构、程序设计步骤、进制转换、基本数据类型、转义字符、常量
4、各种基本数据类型的内存大小在不同位机(32os/64os)之间的区别
5、有符号数(char和整型)的最小负数的绝对值比最大正数大1的原因
3、多分支选择结构、scanf()函数的字符输入回收、循环结构
4、指针的类型、变量作用域、*在C语言中的作用、函数中的变量在程序执行时的声明与释放
1、计算机结构、程序设计步骤、进制转换、基本数据类型、转义字符、常量
1、ascii 及必记字符的ascii值
‘a’= 97
'A' = 65 大小写字符之间相差32
‘0’= 48
‘\0’ = 0
2、不同进制、有无符号与整形和浮点型的关系
1、在c中,实数只有十进制的实数,整型既可以用十进制表示,也可以用八进制、十六进制
2、有符号signed和无符号unsigned 只能用来修饰字符型和整形,不能用来修饰浮点型,因为浮点型的最高位本来就是表示符号位的
3、初识typedef关键字
typedef是用来给已有的数据类型起别名的
4、各种基本数据类型的内存大小在不同位机(32os/64os)之间的区别
指针在32位系统中是4个字节,因为地址就是32位
指针在64位操作系统是8个字节,因为地址就是64位的
5、有符号数(char和整型)的最小负数的绝对值比最大正数大1的原因
比如 char 的范围是-128 ~ 127
可以拆解为-128 ~ -1 U 0 ~ 127 ,左右各128个,加起来是256,满足2^8=256,包含了所有的情况
0 ~ 127 的补码为 0000 0000 ~ 0111 1111
-127 ~ -1 的补码为 1000 0001 ~ 1111 1111,唯独缺少一个1000 0000,那这个补码对应的就是-128
6、补码转原码的两种方式
1、补码--->减1---->取反,得到源码
2、补码的补码就是原码
7、赋的值超出数据类型的范围时的问题
出现这种情况,需要根据此数据类型可容纳的最多Bit位去从右到左截取值的二进制补码,然后填充进去,即是得到值的补码
例如:
char a = 130;
printf("%d\n", a); //得到的结果为-126
unsigned char b = 260;
printf("%d\n", b); //得到的结果为4
还有一种更简洁的方法:转圈去数
比如第一道题,char的范围是【-128,127】,130超出127 三个值,那么就从-128开始,数三个值,-128、-127、-126,即是得到的结果
8、float和double类型的区别
1、float能表示的小数的有效位数是6-7位,double能表示的小数的有效位数是15-16位,超出的位数不保证正确
2、float的格式符是%f, double的格式符是%lf,但是这俩格式符的默认输出小数位数都是6位
3、%n(l)f,n能够控制小数位数
9、转义字符中的\ddd和\xhh
他俩的表示方法为:'\ddd' '\xhh'
比如:'\101' '\x3e'
他们的用法是,'\101' 的二进制为0100 0001,其十进制形式为65,为字符'a'
10、常量
1、常量在内存中的区域是固定的,有一片专门用于存储常量的内存区
2、一般,给变量的赋值就是用常量给变量赋值
2、常量在程序运算中是不能也不会被改变的
3、常量可以是任意的基本类型,分为整形常量、字符常量、浮点型常量、字符串常量、标识常量(宏)等
4、在数学中,常量就是常数,很明显,1++是不对的,因为1 ≠ 1+1,所以常量不能被修改
5、常量的声明一般有两种方式,用const或者定义宏,一旦声明赋初值,就不可被更改
11、宏的注意事项
1、宏名一般用大写,小写也可以,但是为了和普通的变量,区分开来,所以一般用大写!
2、定义宏的语句后没有分号
3、宏函数
3、宏只是一个单纯的替换!!!不会考虑运算符优先级的问题,所以在使用时需要给宏函数每个形参,以及整个表达式都加上括号!!!
4、宏函数的例子
12、字符的一些注意事项
1、数字被定义为字符型后不能直接参与运算,运算的结果实际是该字符的ascii值参与了数值运算
2、字符变量存储字符常量时,实际上是将该字符的ASCII值(无符号整数)存储到内存单元中,反过来,字符常量也能被存储到一个整型变量中,字符和整数在本质上是一样的
2、编程思路、入口函数、数据类型转换、标准输入输出函数
1、编程思路
1、分析建模,写下核心算法
2、画业务逻辑流程图
3、将流程图翻译为C代码
4、将源码编译为可执行目标文件
5、执行目标文件
2、入口函数main()函数
在程序执行时,会先找main()函数,从此函数的第一句开始执行,到最后一句执行完毕后,程序结束
3、数据类型转换
1、隐式转换
隐式转换是自动进行的,通常是由数据类型较小的数据的类型转换为较大的数据类型
1、算术运算时的隐式转换
例如:
int a = 16;
int b = 3;
double c = 3;
printf("除法的结果为:%d\n", a / b); //结果为5
printf("除法的结果为:%lf\n", a / c); //结果为5.333333 ,一个int ,一个double 进行算数运算,得到的结果
的数据类型被隐式转换为较大的double
2、unsigned和signed的两个数进行计算后,结果为较大的unsigned
例如:
char a = 127;
unsigned char b = 3;
printf("%d\n", a+b); //结果为130,很明显,a+b这个表达式的数据类型是较大的unsigned char
2、显式转换(强制转换)
显示转换一般是指,将数据类型较大的数据的类型转换为较小的数据类型
(数据类型)变量名
例如:
float a = 12.43;
printf("%d", (int)a); //结果为12
4、标准输入输出函数的格式化符的区别的一点
scanf("%md", &a);
printf("%md", a);
这个m都是控制宽度的,但是作用有所差别
1、在标准输入函数中,当m小于实际输入时,则会从左到右截取输入的值作为实际输入;当m大于等于实际输入时,则会原样输入
2、在标准输出函数中,当m小于等于实际输出时,则原样输出;当m大于实际输出时,输出右对齐,且左边用空格补齐
3、多分支选择结构、scanf()函数的字符输入回收、循环结构
1、scanf()函数的字符输入回收
scanf("%d %f", &i, &f);
%d、%f在遇到\n \t \r(回车)时,会自动忽略
scanf("%c", &ch);
%c在遇到\n \t \r 时,不会自动忽略,而是将其作为输入给到%c
解决方法:
1、用%*c将\n \t \r吃掉
2、用getchar()函数将\n \t \r吃掉
2、判断一个浮点数是否为0的方法
不能使用float f == 0, 因为f的有效数有限,是个不确定的数,只能用范围去判断:
f < 0.000001 && f > -0.000001
这也是switch(表达式),表达式只能是整型表达式的原因,而不能用实型表达式,case后的标号也只能是整形常量
3、switch_case结构的执行顺序及注意事项
入口:
1、表达式与case后的标号第一次相等的时候
2、当表达式与所有的case都不相等时,从default进入
出口:
1、遇到break
2、没有break时,完全执行完毕才退出
注意:
switch后的表达式只能是整形表达式,case后的标号只能是整形常量
switch case 中不能定义变量,但是case下级的语句块中可以
比如:
switch (整形表达式)
{
//此处不能定义
case 1:
//此处不能定义
if (表达式){
//此处可以定义 int a = 9;
}
}
4、循环
4、指针的类型、变量作用域、*在C语言中的作用、函数中的变量在程序执行时的声明与释放
1、指针的类型
第一行:int a = 5, *pa = &a;
第二行:int ** ppa = &pa;
第三行:*pa = 6;
第四行:**pa = 7;
在上面的语句中,可以知道a是Int 类型的变量,pa是指向int的指针变量,它的类型就是Int *,而ppa是指向int *的变量,它的类型就是Int **; 那么通过指针操作上级数据时,就必须保证等式两边的东西的数据类型一致,比如第三行,两边都是Int类型,第四行,两边也都是Int 类型,第二行,两边都是Int **类型,第一行,两边都是int *类型。
还有一点,类型是float *的不能与int *的做赋值运算,比如:
float b = 9;
pa = &b; //int * ≠ float *
这是错误的,pa是int *,只能存放Int变量的地址,不能存放float变量的地址,这是因为将来指针在对其上级变量操作时,能操作的数据宽度是固定的,比如int *指针只能操作4个字节,而不能操作8个字节的double变量
2、变量作用域
变量在时间(存在时间)和空间(作用域)上可分为:局部变量、全局变量
局部变量:
概念:
在函数内部定义的变量称为局部变量,局部变量仅能被定义该变量的模块内部的语句所使用,换言之,局部变量在自己的代码模块之外是不可见的。
这是因为局部变量的定义是在执行到定义语句时,会在动态存储区域开辟新空间存放此变量,当其所属的语句块结束时,这个空间将被释放,所以外部不可用。
注意:
局部变量定义在函数内时,其作用域是整个函数;定义在函数内的某个语句块内时,其作用域仅是此语句块
。离开此语句块就不可用。
全局变量:
概念:
全局变量必须定义在源代码文件的所有函数之外,且只能被定义一次,其格式为:
【extern】 类型 变量名 = init value; //extern可以被省略,初始化也可以不做
全局变量一旦被定义,就将在编译时分配内存,它是存放在静态存储区域中的,并一直持续到程序结束,而且其作用域是整个源文件,所有的函数均可以使用。
注意:
1、全局变量的定义和声明是不同的,这与局部变量不同,它只能在所有函数外边定义一次,但却可以在函数内部声明多次,声明时不可以赋值,声明仅表示要在这个函数内使用这个全局变量
2、在函数体内部,可以定义一个与全局变量同名的局部变量,而且此局部变量在此函数内部的优先级要比同名的全局变量高,换言之,这个全局变量不起作用;但是如果在函数内部已经声明了一个在外部定义的全局变量时,则不能再定义一个同名的局部变量,否则会报错。
在函数体内部声明全局变量的格式:
extern 类型 变量名;//extern 不可省略,且声明时不可以赋值
3、*在C语言中的不同用法
4、函数中变量的定义空间开辟与释放
只有执行到函数内部的变量的定义语句时,才会为其在内存中开辟空间,当其所属的语句块执行完毕或者函数体被执行完毕时,其在内存中的空间将被释放,之后无法再访问它的值。所以,一般需要将需要的结果及时return出来,作为函数的计算结果进行保存。
5、字符指针,字符串常量
1、字符串常量的特点
1、用双引号“”引起来的叫做字符串常量。eg: “hellowordl”
2、字符串常量本身就是该字符串常量的首地址(首元素的地址),所以我们可以定义一个char * 去引用字符串
char * pc = "hellowrold" //"helloworld"是char *类型
这样通过字符指针pc就可以访问该字符串常量中的内容
*(pc + i) 或 pc[i]
3、字符串常量中的元素内容不能被修改,否则会出现段错误,编译是能够编译过去的,执行时报错
segement fault
出现段错误的原因还有:
访问了空指针或者野指针,空指针是谁也不指,野指针是指的是个随机变量
4、字符串常量的最后一个元素是'\0',这也是判断其结束的标志
6、 sizeof操作符的注意事项
如果一个指针指向了某数组,那么千万不能用sizeof(指针)来计算其指向的数组的大小