开发过程:实验室->市场->存活->标准化
每一个C程序都有个main函数,void表示不返回结果
自顶向下,逐步求精,功能求解
函数:说明部分和定义部分+执行部分
标识符只识别前八个
开发到运行:编辑->预处理->编译->连接->加载->执行
编译:.c或.h; 预处理:对源程序文件作文字转换;编译:debug+产生机器语言程序
连接(超系统数据库之类)
加载
执行
C语言:过程化高级程序设计语言
变量:变量名就是地址
守住要点,各个击破
数值以补码表示:正整数的补码和该数原码相同
负数:绝对值按位取反+1
没写unsigned第一位都是符号位哦
整型的溢出:数值+ 1&符号反过来
整数小数可以任选,但不可以同时都没有
只储存7位有效数字,超出储存位数的值不会被储存= =
避免很大&很小的数直接相加相减
判断x=y?fabs(1e-6)//绝对值函数!
关于e的一些写法要求:
1.e前后的实数和整数均不能省略
2. 价码(后面的指数)必须是整数,前面可以是小数
putchar():putchar('\141');即putchar(a),此处是八进制数
类型 | 标识符 | 有效位 | 比特数 | 取值范围 |
单精度浮点型 | float | 7 | 32 | -3.4 1038 ~ 3.4 1038 |
双精度浮点型 | double | 15 | 64 | -1.7 10308 ~ 1.7 10308 |
长双精度浮点型 | long double | 19 | 128 | -1.2 104932 ~ 1.2 104932 |
几个比较重要的转义字符:
\ b | 退格:到该字符的前一个 |
\t | 用空格补齐8个字符(制表)(虽然有8个光标,但只占一个字符) |
\r | 回到起始位置 |
\\ | 即为\ |
个体插入()括号里面什么字符都没有
算术运算符>关系运算符>赋值运算符
位运算:二进位组成的位串信息
位反:两个都为真才为真,其中一个为假即为假
用法:截取某几位
eg:截取最低七位:x&0177
保留前六位:x&0077
位或:一个为真即为真
典型用法:将一个位串的某几位置设为1;eg:x|017
位异或运算:不同为真,相同为假
用法:将某几位取反:x^017:将最低四位取反
位反:~0=1,~1=0
移位:<<即x2,>>即除以2,空位用0补齐
sizeof(类型名):返回某种类型所占字节数
p1&&p2<->!(!p1||!p2)
go away from goto!
(破坏结构化.jpg)
数组名:开始地址
_______________________________________________________________
eg:在数组中找值等于变量key的元素的下标
哨兵:a[n]=key;
for(i=0;key!=a[i];++i)
即oop中的iterator!=end()
二分法also
冒泡排序?多次将相邻两个比大小
小的值冒上来,大的值沉下去
改进:记录最后一次交换处,起始处到k的时候直接停掉
————————————————————————————————————
文件操作:fscanf(fp,"%d",&x);
数组:直接存取类
特点:有限,有序,数据类型相同
void swap(int *a,int *b)
{
int temp=*a;
*a=*b;
*b=temp;
}
swap: swap(&arr[i],&arr[i+1]);
测试用例:1. 打包 2. 单独测
_________________________________________________________________________
二维数组的存储:a[0][0]->a[0][1]->a[0][2]->........
a[3][4]={{1},{5},{9}}a[0][0]=1,a[1][0]=5,a[2][0]=9;
赋完初值:一维长度可不定,二维长度不可少;
a4[2][3]={1,2,3,4}
自顶向下&自底向上!
整形数组亦可存放字符(就是有点费空间)
字符序列中没定义的量都为'\0'
输入字符串的时候不用加&,因为数组名即为其开始地址,但指定数组位置(比如a[i])的时候,就要加&了
输入一串包括空格符在内的一行字符,要用gets()
字符串不能使用==或!=等运算!
大写英文字符转化为小写:strlwr() ;小写转大写strupr()
指针形参:引用指针变量,改变环境变量的值
_____________________________________________________________________________
嵌套调用:nested
很多离散数学里面的概念都是递归定义的!
递归的正确打开方式:
(1)根据递归定义给出递归函数&过程
(2)要有递归结束条件&边界
(3)递归过程向递归边界逼近(防止震荡时的无限递归)
对数组,如果要在函数里面引用,具体表达方式为:
int rsum(int *a,int n)
{
if(n==0) return 0;
return *a+rsum(a+1,n-1);
}
先调用,后返回!
__________________________________________________________________________
不要过多使用全局变量(占内存)
变量的可见性&存在性:
可见性:可访问性。该范围即为作用域
存在性:占有存储空间,但值被保留
变量的存储类:
重要概念:存在性、可见性
自动 auto
主要特点:临时性;函数(体)结束时,系统自动收回存储空间
其可见性与存在性一致
每次进入函数&复合语句时,第一次对自动变量的引用应是为其设定初值
静态 static
在变量前冠以关键词 static(这个必须的)
编译时就对其存储空间预分配,程序执行前就被确定储存单元
仅局限于定义它的函数或复合语句,但在作用域之外不可访问
在作用域内有专用的、永久的储存
下一次调用时,该变量已有值就是上一次调用结束后该变量的值
(部分作用同全局变量,只是在外部不可访问)
假如没赋初值,就会自动赋一个二进制全为0的初值
外部 extern
在正式定义变量之前对外部变量进行声明,在后面再定义,便可以扩展作用域
eg:
假如把外部变量声明为全局变量?就是不让源程序中其他程序访问
寄存器 register
直接从寄存器内读取,速度更快(但现在用这些必要性不大)
只有int、char和指针类型的自动变量和形参才可能是寄存器类型
____________________________________________________________________________
递归定义:分成不相容的几种情况
编译预处理命令简介:
先对源程序中一些特殊的预处理命令做解释,产生一个新的源程序;然后再对新的源程序进行通常的编译
C语言提供的预处理命令:宏定义、文件包含、条件编译和行控制
所有预处理命令行都以字符“#”和预处理命令开头
宏定义:#define 标识符 字符序列
常用到的:#define EOF -1
#define NL printf("\n");
宏定义一行不够时,在回车符前先加\,再换行,中间不能加其他字符
还能undefine,还可以被重新定义代替
可改变数组元素不变的不足
不做任何的语法检查!!!
#define 标识符(形式参数表) 字符序列
eg: #define MAX(A,B) ((A)>(B)?(A):(B))
cmp: 函数&宏定义
函数求出实参表达式的值,宏定义不传值
函数临时分配存储单元,宏定义在编译之前完成,不需要临时分配存储单元(根本就不会分配内存)
宏定义只是相应字符的自然连接,没有类型概念,只有字符序列的对应关系
函数调用可以返回一个值,宏调用获得希望的C代码