1,什么是C语言;
1.1面向过程编程的高级语言;既可以像高级语言那样使用逻辑算法来编程,也具备低级语言面向计算机硬件编程;
1.2使用的编译系统有GCC,VisualC++等;编译后生成.exe可执行文件;
2,数据类型;
2.1基本类型:整型,浮点型,字符型;
int:32位编译器4字节,64位编译器8字节;
short int :比int的短;2字节;
long int :比int的长;8字节;
float : 4字节;
double : 8字节;
char :一个字节;
2.2构造类型:数组类型,结构体类型(struct),共用体类型(union),枚举类型(enum);
2.3指针类型:变量即地址,使用*指向符来指向变量中的内容;
2.4空类型(void):主要用于对函数返回值的限制;
3,预处理命令:#
3.1作为宏定义使用:#define 大写宏名 (宏定义不是C语句,所以不需要用分号结束语句;)
3.1.1字符串中的宏名不进行替换;
3.1.2宏定义只作为字符串替换,不分配内存空间;
3.1.3宏定义可以使用表达式替换,但是表达式参数最好带括号保护运算的优先级;
3.1.4宏名的定义放在文件的开始,或者独立的文件中;
3.1.5宏名使用#undef结束宏名的作用域;
3.2作为文件包含指令使用:#include
3.2.1#include<file.h> : 告诉编译器在头文件库中寻找需要包含的文件;
3.2.2#include"file.h" : 优先在当前目录下寻找需要包含的文件;
3.3作为条件编译使用:#if #elif #endif
#ifndef 宏名 #endif:这种用法可以用来阻止编译器函数被多次包含,而多次编译,导致的编译器报错函数已经存在;
3.4#line 行号["file_name"]命令:说是用于调试用途;不太理解什么作用;
3.5#pragma :比上面的3.4还迷糊;这两个命令不太理解,说不来;
4,函数声明:int func(int a,int b);
4.1目的 : 让编译器知道函数的返回值类型,名称,参数等信息;(是C语句有分号)放在哪里没有关系;
4.1.1 声明类型auto:平时变量的声明默认为auto,可以省略;要使用时由系统自动分配内存,调用完成后释放内存存储空间;
4.1.2 声明类型static : 变量的初始化只在第一次起作用,之后的初始化不起作用,变量有时序记忆性;
4.1.3 声明类型extern : 声明外部变量可供同工程源文件调用;
4.1.4 声明类型Register : 变量的值放在硬件寄存器中,调用时不必占用内存;
ps:硬件寄存器的地址是无法通过内存获得的;寄存器的使用不占用内存地址;
5,函数定义
5.1函数定义的作用:让编译器知道函数的功能 eg: int func(int a,int b){ ...; }
5.1.1在一个函数体内不能嵌套定义新的函数,但是可以调用其他的函数;(编译的时候可能要考虑前面提到的函数被多次包含的编译错误);
6,
6.1 case语句中如果某个case后面没有break;则就会顺序执行下一个语句,直到遇见break;这种模式可以用来作为多路开关;
6.2if else语句加上他们后面的代码段才是完整的C语句,用大括号将代码段括起来代表一个整体的小模块;
6.3 ? :是C语言中唯一的一个三目运算符; eg: (表达式判断)?(为真返回此处值):(为假返回此处值)
6.4 do{ ... }while(); 注意这个判断语句的分号是在括号边上的;其他的判断语句的括号边上都没有分号;
6.5 void main( int argc,int * argv[ ] ) 是main函数的固定参数;
6.5.1 argc 参数记录命令行的命令和参数个数;
6.5.2 argv 参数记录命令行的命令和参数个数的内容;
7,数组
7.1:数组定义: eg: int array[10]; 数组类型 数组名[ 成员个数 ];(数组个数为常数,是定值)
7.2:数组类型:整型数组,浮点型数组,字符型数组,指针数组;
7.3:C语言中数组的引用只能逐个引用;数组的下标从0开始引用;注意数组定义的时候用的不是下标而是个数;
7.4: 当数组作为实参传递给函数的时候:
7.4.1:没有括号的数组等同于该数组第一个元素的地址;实参中传递的就是首地址;
7.4.2 : 数组在主调函数和被调函数中应该分别定义名字;
8,指针
8.1:为什么要使用指针; 因为函数调用过程中数据的传递是实参到形参的单向传递,改变后的形参没有办法返回给形参;
所以我们使用指针作为函数形参,参数传递是对地址里的内容进行修改,修改后的内容就可以保持;
8.2 : 指针变量定义:指针变量中存放的是地址,用*指向符来指向地址取出内容;未经赋值的指针不能使用;
可以使用取地址符&将一个变量的地址取出,然后赋值给指针进行操作;
int a;
int * p=& a;
8.3:
8.3.1:不允许将数值赋值给指针变量;
8.3.2:*与&的优先级相同,自右向左运算;
8.3.3:指针的自加加加的是一个上一个数据类型的长度以供下一个数据类型使用;
8.3.4:数组的名字就是数组在内存的首地址; p=&a[0] (p=a) ; (p+i)可用循坏遍历数组地址, *(p+i)可用循坏遍历数组内容;
8.4 : 指针数组:数组中的元素均为指针变量的数组;指针数组占用的空间要小于字符串数组;
eg: char * arrayname[数组长度];
遍历指针数组需要使用指向指针的变量;指向指针的变量在定义时为 eg:(char * *p; ) 但是使用起来和只有一个*的指针变量是一样的;
两个*为什么呢?因为指针数组里是地址嘛,所以被用来赋值的指针内容也应该是地址;
8.5:指针二维数组;
&a[m][n]表示的是数组第m行第n列元素的地址;
a[m]+n 表示的是二维数组第m行第n列元素的地址;
*(a+m)+n表示的是二维数组第m行第n列的地址;
哪哪,这里的二维数组怎么表示都是地址,真是神奇,先记住怎么用,等会有点事,急着做完,我下次再好好想想这个问题和一维数组的表示差别;
8.6:指针函数;返回的数据类型是指针类型的函数;
eg: int fun *(int a, int b); 表示此函数是指针类型的函数,返回的值是一个指向整型的指针变量;
8.7:指向函数的指针;
数据类型 (*指针名字)(函数参数列表); 指针名字=函数名字;
eg: int fun(int a,int b){....} //定义一个函数;
int (*p)(int,int); //在主函数中定义一个函数指针,带上它的参量;
p=fun; //为函数指针定义指向什么函数;
c=(*p)(x,y); //将函数指针的返回值存入c中;