Minhal 发表于 2016-8-15 20:25:53

C基础班讲义(新手老手都可以来看)

本帖最后由 Minhal 于 2016-8-15 22:43 编辑

C基础班讲义
目录
1      第一个c语言的hello world      14
1.1      include头文件包含      14
1.2      main函数      14
1.3      注释      14
1.4      {}括号和代码块      14
1.5      声明      14
1.6      C语言自定义名字的要求      14
1.7      return语句      15
2      C语言的编译      15
2.1      编译过程      15
2.2      gcc编译选项      15
2.3      printf执行原理      16
2.4      CPU32位64位简介      17
3      C语言中的数据类型      18
3.1      常量      18
3.1.1      #define      18
3.1.2      const      19
3.2      字符串常量      19
3.3      位,字节,字      19
3.3.1      位      19
3.3.2      二进制      19
3.3.3      十进制      19
3.3.4      八进制      20
3.3.5      十六进制      20
3.3.6      字节      20
3.4      sizeof关键字      20
3.5      十进制,二进制,八进制,十六进制      21
3.6      int类型      21
3.6.1      int常量,变量      21
3.6.2      printf输出int值      23
3.6.3      printf输出八进制和十六进制      23
3.6.4      short,long,long long,unsigned int      23
3.6.5      整数溢出      23
3.7      char类型      24
3.7.1      char常量,变量      24
3.7.2      printf输出char      24
3.7.3      不可打印char转义符      24
3.7.4      char和unsigned char      25
3.8      浮点float,double,long double类型      25
3.8.1      浮点常量,变量      25
3.8.2      printf输出浮点数      25
3.9      类型限定      25
3.9.1      const      25
3.9.2      volatile      25
3.9.3      register      26
4      字符串格式化输出和输入      26
4.1      字符串在计算机内部的存储方式      26
4.2      printf函数,putchar函数      26
4.3      scanf函数与getchar函数      27
5      运算符表达式和语句      28
5.1      基本运算符      28
5.1.1      =      28
5.1.2      +      28
5.1.3      –      28
5.1.4      *      28
5.1.5      28
5.1.6      %      28
5.1.7      +=      28
5.1.8      -=      28
5.1.9      *=      29
5.1.10      =      29
5.1.11      %=      29
5.1.12      ++      29
5.1.13      --      29
5.1.14      逗号运算符      29
5.1.15      运算符优先级      29
5.2      复合语句      30
5.3      类型转化      30
6      条件分支语句      30
6.1      关系运算符      30
6.1.1      <      30
6.1.2      <=      30
6.1.3      >      30
6.1.4      >=      31
6.1.5      ==      31
6.1.6      !=      31
6.2      关系运算符优先级      31
6.3      逻辑运算符      31
6.3.1      &&      31
6.3.2      ||      32
6.3.3      !      32
6.4      if      33
6.5      if else      34
6.6      if else if      34
6.7      switch与break,default      34
6.8      条件运算符?      34
6.9      goto语句与标号      34
7      循环语句      34
7.1      while      34
7.2      continue      34
7.3      break      35
7.4      do while      35
7.5      for      35
7.6      循环嵌套      35
8      整数在计算机内部的存储方式      36
8.1      原码      36
8.2      反码      36
8.3      补码      36
9      数组      37
9.1      一维数组定义与使用      37
9.2      数组在内存的存储方式      37
9.3      一维数组初始化      37
9.4      二维数组定义与使用      41
9.5      二维数组初始化      41
10      字符串与字符数组      41
10.1      字符数组定义      41
10.2      字符数组初始化      41
10.3      字符数组使用      42
10.4      随机数产生函数rand与srand      42
10.5      用scanf输入字符串      42
10.6      字符串的结束标志      43
10.7      字符串处理函数      43
10.7.1      gets      43
10.7.2      fgets函数      43
10.7.3      puts函数      43
10.7.4      fputs函数      44
10.7.5      strlen,字符串长度      44
10.7.6      strcat,字符串追加      44
10.7.7      strncat,字符串有限追加      44
10.7.8      strcmp,字符串比较      44
10.7.9      strncmp,字符串有限比较      44
10.7.10      strcpy字符串拷贝      45
10.7.11      strncpy字符串有限拷贝      45
10.7.12      sprintf,格式化字符串      45
10.7.13      strchr查找字符      45
10.7.14      strstr查找子串      45
10.7.15      strtok分割字符串      45
10.7.16      atoi转化为int      45
10.7.17      atof转化为float      46
10.7.18      atol转化为long      46
11      函数      47
11.1      函数的原型和调用      47
11.2      函数的形参与实参      48
11.3      函数的返回类型与返回值      48
11.4      main函数与exit函数      49
11.5      函数的递归      49
11.5.1      递归的过程分析      49
11.5.2      递归的优点      54
11.5.3      递归的缺点      54
11.6      多个源代码文件程序的编译      54
11.6.1      头文件的使用      54
11.6.2      #include与#define的意义      54
11.6.3      #ifndef与#endif      54
11.7      函数的二进制封装      55
11.7.1      exe加载dll的说明      55
11.7.2      动态库中代码与位置无关的说明图      56
11.7.3      linux编写so文件的方式      56
11.7.4      linux使用so      56
11.7.5      配置profile文件可以在当前目录下查找so文件      57
11.8      作业描述      57
12      指针      58
12.1      指针      58

**** Hidden Message *****

——————————————————————————

这个讲义把C语言的基础框架罗列了出来,涵盖范围比较全,但肯定没有c语言书籍那么细致,不建议做学习资料,可以用来参考复习。

下面的图片都没传上来所以再发个pdf 供大家学习。
解压密码:
**** Hidden Message *****

另外,觉得不错的话欢迎用下面的打赏“砸我”{:10_257:}{:9_240:}

Minhal 发表于 2016-8-15 20:27:40

本帖最后由 Minhal 于 2016-8-15 20:29 编辑

1 第一个c语言的hello world1.1 include头文件包含头文件包含,写法#include <文件名>,1.2 main函数这个就是C语言程序的入口,所有的C程序都是从main开始执行,一个C的源程序必须有一个main函数,也只能有一个main函数1.3 注释//注释一行/* */代表块注释,可以注释多行代码
1.4 {}括号和代码块代表一个代码单元1.5 声明C语言规定,所有的变量和函数必须先声明,然后才能使用.1.6 C语言自定义名字的要求可以使用大小写字母,下划线,数字,但第一个字母必须是字母或者下划线字母区分大小写变量名最好用英文,而且要有所含义,通过变量的名称就能猜测变量的意思。
1.7 return语句在C语言当中任何函数遇到return代表这个函数停止,当main函数遇到return,代表整个程序退出return代表函数的返回值,如果返回类型是void,可以直接写return,而不需要返回任何值2 C语言的编译2.1 编译过程
2.2 gcc编译选项-o代表指定输出文件名-E代表预编译预编译处理include的本质就是简单的将include中的文件替换到c文件中如果include包含的头文件在系统目录下,那么就用#include <>,如果包含的文件在当前目录下,那么用#inlclude “”-S代表汇编-c代表编译2.3 printf执行原理

2.4 CPU32位64位简介
一个字节是8个bit,一个字是两个字节,整型4个字节8位寄存器AL   00000000256
16位寄存器AX    AL AH 00000000000000001111111111111111   
四个通用寄存器AXBXCXDX
32位寄存器EAX 0000000000000000000000000000000000000000000000 1111111111111111111111111111111111EBXECXEDX
64位寄存器REAXREBXRECXREDX
3 C语言中的数据类型重点:**3.1 常量常量就是在程序中不可变化的量,常量是不可被赋值的。3.1.1 #define#define的本质就是简单的文本替换通过#define定义的常量,在C语言里面一般叫宏定义3.1.2 constconst定义一个变量,但是这个变量的值只能在定义的时候赋予,之后就不可以修改。对于const类型的变量,一定要在定义的时候给变量赋初值,不然定义之后就无法赋值了。
3.2 字符串常量在C语言当中“”引用的字符串都是字符串常量,常量一旦定义也是不可以被修改的。3.3 位,字节,字3.3.1 位计算机内部都是二进制的,一个二进制的位,就叫做一个bit,就是一位3.3.2 二进制逢二加1,在二进制表达数的时候是只有0和1,而没有2这个数的二进制最大表示的数,就是2几次幂对于8位的CPU来讲,最大表达的数是2的8次幂3.3.3 十进制逢10加1,只有从0 到9的数,没有10这个数,
3.3.4 八进制从0到7,逢8加1在C语言中八进制是数字前面加03.3.5 十六进制0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,10逢16加1,在C语言当中表达一个十六进制数的方式,数字前面加0x前缀3.3.6 字节8个bit为代表一个字节3.4 sizeof关键字sizeof与size_t类型sizeof是计算数据在内存当中占多大空间的,单位字节由于sizeof永远返回的是一个大于等于0的整数,所以如果用int来表示sizeof的返回值就不合适,size_t一般就是一个无符号的整数.3.5 十进制,二进制,八进制,十六进制
3.6 int类型3.6.1 int常量,变量一个int型数据占据4个字节的内存大小,在16位操作系统下,int是2个字节,在32和64位操作系统下,int是4个字节。int a;//代表在内存当中开辟一个4个字节大小的空间a = 10;//代表4个字节的空间内容是常量10小端对齐和大端对齐高地址放高位,底地址放低位---小端对齐高地址放低位,底地址放高位—大端对齐对于大型unix CPU都是按照大端对齐方式处理int,但对于x86构架CPU,还有ARM,是小端对齐的




3.6.2 printf输出int值int a = 0x100;//十六进制printf(“%d”,a);%d的意思是按照10进制打印一个整数%x%X,输出十六进制的时候是用大写的ABCDEF还是小写的abcdef,3.6.3 printf输出八进制和十六进制%o3.6.4 short,long,long long,unsigned int 在32位系统下:short = 2个字节long和int一样,是4字节long long 是8个字节在64位操作系统下int,4个字节long 在大多数64位系统下8个字节unsigned int//无符号整数unsigned long//无符号的长整数unsigned short//无符号短整数
9l,9L,9ll,9LL,9u,9ull,9ULL3.6.5 整数溢出当把一个大的整数赋值给小的整数,叫溢出。int I = 0x12345678short a = I;当一个int赋值给short,会将高位抛弃,3.7 char类型3.7.1 char常量,变量char是字符型,代表一个字节的内存char在内存当中,有符号最大7f,无符号,最大ffunsigned charchar的本质就是一个字节,一个BYTE3.7.2 printf输出char%c3.7.3 不可打印char转义符a,警报退格换行回车      制表符斜杠’单引号”双引号?问号3.7.4 char和unsigned charchar取值范围为-128到127unsigned char为0-2553.8 浮点float,double,long double类型3.8.1 浮点常量,变量float f = 2.5;double f1 = 3.1415926
3.8.2 printf输出浮点数
%f,%Lf3.9 类型限定3.9.1 constconst限定一个变量的值不可以改变3.9.2 volatile告诉编译器不要自作聪明的给我优化代码,把我的变量优化的寄存器里面计算,只要是volatile类型变量,每一步都需要从内存当中读取。
3.9.3 registerregister告诉编译器,这个变量只是用寄存器就好,提高效率,所以说register只是一个建议,而不是必须的结果。

Minhal 发表于 2016-8-15 20:34:49

4 字符串格式化输出和输入重点:*4.1 字符串在计算机内部的存储方式字符串是内存中一段连续的char空间,以’\0’结尾字符串就是0结尾的连续char的内存4.2 printf函数,putchar函数printf格式字符
字符对应数据类型含义
d int接受整数值并将它表示为有符号的十进制整数
hdShort int短整数
huUnsigned short int无符号短整数
ounsigned int无符号8进制整数
uunsigned int无符号10进制整数
x / Xunsigned int无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF
ffloat或double单精度浮点数或双精度浮点数
e / Edouble科学计数法表示的数,此处"e"的大小写代表在输出时用的“e”的大小写
cchar字符型。可以把输入的数字按照ASCII码相应转换为对应的字符
s / Schar * / wchar_t *字符串。输出字符串中的字符直至字符串中的空字符(字符串以'\0‘结尾,这个'\0'即空字符)
pvoid *以16进制形式输出指针
%%输出一个百分号
printf附加格式
字符含义
l附加在d,u,x,o前面,表示长整数
-左对齐
m(代表一个整数)数据最小宽度
0将输出的前面补上0file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA829.tmp.jpg直到占满指定列宽为止file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA82A.tmp.jpg不可以搭配使用file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA82B.tmp.jpg-file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA82C.tmp.jpgfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA82D.tmp.jpg
N(代表一个整数) 宽度至少为n位file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA82E.tmp.jpg不够以空格填充file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA82F.tmp.jpg
printf是打印一个字符串putchar是打印一个字符 4.3 scanf函数与getchar函数 5 运算符表达式和语句重点:***5.1 基本运算符5.1.1 =数据对象:泛指数据在内存的存储区域左值:表示可以被更改的数据对象右值:能赋给左值的量5.1.2 + 5.1.3 – 5.1.4 * 5.1.5 / 5.1.6 %取模,取余数 5.1.7 +=int a = 10;a = a + 5;可以简写成a += 5;5.1.8 -=a = a – 5;a -= 5;5.1.9 *=a = a * 5;a *= 5;5.1.10 /= 5.1.11 %= 5.1.12 ++笔试面试特别容易考,也是特别容易出错的地方5.1.13 -- 5.1.14 逗号运算符int I = 6 + 5, 3 + 2逗号表达式先求逗号左边的值,然后求右边的值,整个语句的值是逗号右边的值。5.1.15 运算符优先级
优先级运算符结合性
1++(后缀),--(后缀),()(调用函数),{}(语句块),.,->从左到右
2++(前缀),--(前缀),+(前缀),-(前缀),!(前缀),~(前缀),sizeof,*(取指针值),&(取地址),(type)(类型转化)从右到左
3*, /, %从左到右
4+,-从左到右
5<< >>从左到右
6< > <= >=从左到右
7== !=从左到右
8&从左到右
9^从左到右
10|从左到右
11&&从左到右
12||从左到右
13?从右到左
14=,*=,%=,+=,-=,<<=,>>=,&=,|=,^=从右到左
15,(逗号运算符)从左到右
5.2 复合语句{}代码块5.3 类型转化                double d = 10.2;                int a = d;//隐式转换                 int a1 = 3;                int a2 = 2;                double mid = (double)a1 / (double)a2;//显示的强转                printf("mid = %f\n", mid);6 条件分支语句重点:***6.1 关系运算符在C语言中0代表假,非0代表真,在计算机程序判断是根据一个条件返回是真还是假来做不同的操作。6.1.1 < 6.1.2 <= 6.1.3 > 6.1.4 >= 6.1.5 ==一个=号在C语言里面是赋值的,不是比较的,但是很多初学者爱犯一个严重的错误,就是用=号来比较两个数是否相等6.1.6 !=!=6.2 关系运算符优先级前四种相同,后两种相同,前四种高于后两种优先级6.3 逻辑运算符6.3.1 &&
逻辑与file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA840.tmp.jpg 6.3.2 ||逻辑或file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA841.tmp.jpg 6.3.3 !逻辑非file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA842.tmp.jpg 6.4 iffile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA853.tmp.jpg 6.5 if else两路分支if语句,只可能执行一路,不可能同时执行两路,也不可能两路都没有被执行6.6 if else ifif else if 这种于语法可以实现多路的分支,但只有一路被执行。else永远是和最近的一条if语句配对。6.7 switch与break,defaultswitch是为多重选择准备的,遇到break语句,switch就终端执行6.8 条件运算符?一个求绝对值的例子
        int i = -8;        int x = (i < 0) ? -i: i;
?号用法当?号        前面括号内容为真的时候,执行?号之后冒号之前的语句,否则执行冒号之后的语句6.9 goto语句与标号尽量不要在程序当中使用goto语句,7 循环语句重点:***7.1 whilewhile(条件),如果条件为真,那么循环就执行,否则循环退出7.2 continuecontinue意思是跳过下面语句,继续执行循环7.3 breakbreak中断循环,7.4 do whiledo        语句while (条件);对于do while来讲,至少能执行一次,7.5 for可以指定循环次数的语句7.6 循环嵌套特别需要掌握的技术,file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA854.tmp.jpg

Minhal 发表于 2016-8-15 20:39:30

本帖最后由 Minhal 于 2016-8-15 20:48 编辑


这里的1是第8章,7是第14章

1 整数在计算机内部的存储方式重点:****1.1 原码将最高位做为符号位(0代表正,1代表负),其余各位代表数值本身的绝对值
+7的原码是00000111-7的原码是10000111+0的原码是00000000-0的原码是10000000
1.2 反码一个数如果值为正,那么反码和原码相同一个数如果为负,那么符号位为1,其他各位与原码相反
+7的反码00000111-7的反码11111000-0的反码11111111
1.3 补码原码和反码都不利于计算机的运算,如:原码表示的7和-7相加,还需要判断符号位。正数:原码,反码补码都相同负数:最高位为1,其余各位原码取反,最后对整个数 + 1
-7的补码:= 10000111(原码)111111000(反码)11111001(补码)+0的补码为00000000-0的补码也是00000000
补码符号位不动,其他位求反,最后整个数 + 1,得到原码
用补码进行运算,减法可以通过加法实现
7-6=17的补码和-6的补码相加:00000111 + 11111010 = 100000001进位舍弃后,剩下的00000001就是1的补码
-7+6 = -1-7的补码和6的补码相加:11111001 + 00000110 = 1111111111111111是-1的补码
2 数组重点:**内存连续,并且是同一种数据类型的变量,C语言的数组小标好是从0开始的,到n-1.2.1 一维数组定义与使用类型 变量名称[数组元素的个数];2.2 数组在内存的存储方式在内存当中是连续的内存空间地址。2.3 一维数组初始化int array = {0};//将数组所有元素都初始化为0int array = {0,1,2,3,4,5,6,7,8,9}数组中找最大值思路file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADA7.tmp.jpg 数组中找第二大值思路file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADA8.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADA9.tmp.jpg 逆置数组思路file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADAA.tmp.jpg 测量楼宇高度的说明file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADAB.tmp.jpg 测量地球太阳距离的说明file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADAC.tmp.jpg 测量太阳木星距离的说明file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADBD.tmp.jpg 2.4 二维数组定义与使用int array;//12个元素的二维数组2.5 二维数组初始化
int a = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
3 字符串与字符数组重点:***3.1 字符数组定义char buf;对于C语言字符串其实就是一个最后一个元素为’\0’的char数组.3.2 字符数组初始化char buf[] = “hello world”;3.3 字符数组使用 3.4 随机数产生函数rand与srand头文件stdlib.h
        #include <time.h>int t = (int)time(NULL);        srand(t);        for (int i = 0; i < 10; i++)        {                printf("%d\n", rand());        }

3.5 用scanf输入字符串char buf = {0};scanf(“%s”, buf);scanf("请输入i的值%d", &i);3.6 字符串的结束标志file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADBE.tmp.jpg 3.7 字符串处理函数3.7.1 getsgets没有解决缓冲区溢出的问题.3.7.2 fgets函数gets函数不检查预留缓冲区是否能够容纳用户实际输入的数据。多出来的字符会导致内存溢出,fgets函数改进了这个问题。由于fgets函数是为读取文件设计的,所以读取键盘时没有gets那么方便
        char s = { 0 };        fgets(s, sizeof(s), stdin);
3.7.3 puts函数puts函数打印字符串,与printf不同,puts会在最后自动添加一个’\n’
        char s[] = "hello world";        puts(s);
3.7.4 fputs函数fputs是puts的文件操作版本,
        char s[] = "hello world";        fputs(s, stdout);
3.7.5 strlen,字符串长度strlen返回字符串的长度,但是不包含字符串结尾的’\0’char bufsizeof(buf);//返回的是数组buf一共占据了多少字节的内存空间.3.7.6 strcat,字符串追加char str1;char str2;strcat(str1, str2);//把str2追加到str1的后面str1一定要有足够的空间来放str2,不然会内存溢出.3.7.7 strncat,字符串有限追加strncat(str1, str2, sizeof(str1) – strlen(str1) - 1); 3.7.8 strcmp,字符串比较strcmp(a, “str”);//如果两个参数所指的字符串内容相同,函数返回03.7.9 strncmp,字符串有限比较strncmp(str, “exit”, 4);3.7.10 strcpy字符串拷贝strcpy(str, “hello world”);//存在溢出的问题,3.7.11 strncpy字符串有限拷贝strcpy(str, “hello world”, 7);3.7.12 sprintf,格式化字符串printf是向屏幕输出一个字符串sprintf是向char数组输出一个字符串,其他行为和printf一模一样sprintf也存在缓冲区溢出的问题3.7.13 strchr查找字符strchr(str, ‘c’);返回值是字符’c’在字符串str中的位置3.7.14 strstr查找子串3.7.15 strtok分割字符串字符在第一次调用时strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL每次调用成功则返回指向被分割出片段的指针
        char buf[] = "abc@defg@igk";        char *p = strtok(buf, "@");;        while (p)        {                printf("%s\n", p);                p = strtok(NULL, "@");        }
3.7.16 atoi转化为int 3.7.17 atof转化为float 3.7.18 atol转化为long file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADCE.tmp.jpg 作业说明:不可以用任何已有的函数,完全自己写代码,完成十进制字符串转化为十进制的整数作业思路:file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADCF.tmp.jpg 4 函数重点***4.1 函数的原型和调用在使用函数前必须定义或者声明函数
double circle(double r);int main(){        double length = circle(10);        printf("length = %f\n", length);        return 0;} double circle(double r){        return 2 * 3.14 * r;}
4.2 函数的形参与实参在调用函数的时候,函数大多数都有参数,主调函数和被调用函数之间需要传递数据。在定义函数时函数名后面括弧中的变量名称为“形式参数”,简称形参。在调用函数时,函数名后面括号中的变量或表达式称为“实际参数”,简称实参。1形参在未出现函数调用时,他们并不占用内存单元,只有在发生函数调用的时候形参才被分配内存,函数调用完成后,形参所占的内存被释放2实参可以是变量,常量或者表达式3在定义函数时,一定要指定形参的数据类型4形参与实参的数据类型一定要可兼容5在C语言中,实参与形参的数据传递是“值传递”,即单向传递,只由实参传递给形参,而不能由形参传递给实参。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADE0.tmp.jpg 4.3 函数的返回类型与返回值1函数的返回值通过函数中的return获得,如果函数的返回值为void可以不需要return语句。2函数return语句中的返回值数据类型应该与函数定义时相同。3如果函数中没有return语句,那么函数将返回一个不确定的值。4.4 main函数与exit函数在main函数当中遇到return语句,代表整个程序结束。在子函数当中遇到return代表子函数结束。不论程序的任何位置调用exit函数,代表整个程序退出。函数的学习难点是递归 4.5 函数的递归函数可以调用自己,这就叫函数的递归
void recurse(int i){        if (i > 0)        {                recurse(i - 1);        }        printf("i = %d\n", i);} int main(){        recurse(10);        return 0;}
4.5.1 递归的过程分析
void up_down(intn){        printf("in %d, location %p\n", n, &n);        if (n < 4)                up_down((n + 1));        printf("out %d, location %p\n", n, &n);} int main(){        up_down(1);        return 0;}
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADE1.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADE2.tmp.jpg 有n个人排成一队,问第n个人多少岁,他回答比前面一个人大2岁,再问前面一个人多少岁,他回答比前面一个人大2岁,一直问到最后问第一个人,他回答10岁
int age(int n){        int i;        if (n == 1)                i = 10;        else                i = age(n - 1) + 2;        return i;}
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADE3.tmp.jpg 将10进制数转化为二进制数的例子234在十进制下为2 * 10的2次方 + 3 * 10的1次方 + 4*10的0次方。奇数的二进制最后一位一定是1,偶数的二进制最后一位一定是0。可以通过 number % 2 得到二进制形式的最后一位,如果要将一个完整的整数转化为二进制就需要用到递归函数。在递归调用之前,计算 number % 2的值,然后在递归调用语句之后进行输出,这样计算出的第一个数值反而在最后一个输出。为了得出下一个数,需要把原数除以2,这种计算相当于十进制下把小数点左移一位,如果此时得出的数是偶数,,则下一个二进制的数值是0,如果得出的是奇数,那么下一个二进制数为1。直到被2除的结果小于2,就停止递归。
void to_binary(unsigned int n){        unsigned int i = n % 2;        if (n >= 2)                to_binary(n / 2);        printf("%c", i + 0x30);}
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADF3.tmp.jpg 斐波那契数列例子斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...第0项是0,第1项是第一个1。这个数列从第2项开始,每一项都等于前两项之和。
int fib(int n){        if (n == 0)                return 0;        if (n == 1)                return 1;        if (n > 1)                return fib(n - 1) + fib(n - 2);}
汉诺塔的例子有三根针1,2,3。1针上有4个盘子,盘子大小不等,大的在下,小的在上,要求把这4个盘子从1针一到3针,在移动过程中可以借助2针,每次只允许移动一个盘子,并且在移动过程中在三根针上都要保持大盘子在下,小盘子在上。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsADF4.tmp.jpg 可以分为以下步骤:1、将1针上n-1个盘借助3针移动到2针上;2、将1针上剩下的一个盘移动到3针上;3、将n-1个盘从2针借助1针移动到3针上。
void hanoi(int n, int one, int two, int three){        if (n == 1)                printf("%d->%d\n", one, three);        else        {                hanoi(n - 1, one, three, two);                printf("%d->%d\n", one, three);                hanoi(n - 1, two, one, three);        }}
4.5.2 递归的优点递归给某些编程问题提供了最简单的方法4.5.3 递归的缺点一个有缺陷的递归会很快耗尽计算机的资源,递归的程序难以理解和维护。 4.6 多个源代码文件程序的编译4.6.1 头文件的使用如果把main函数放在第一个文件中,而把自定义函数放在第二个文件中,那么就需要在第一个文件中声明函数原型。如果把函数原型包含在一个头文件里,那么就不必每次使用函数的时候都声明其原型了。把函数声明放入头文件是很好的习惯。4.6.2 #include与#define的意义 4.6.3 #ifndef与#endif 4.7 函数的二进制封装4.7.1 exe加载dll的说明file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE05.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE06.tmp.jpg 4.7.2 动态库中代码与位置无关的说明图file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE07.tmp.jpg 4.7.3 linux编写so文件的方式1首先gcc编译的时候要加-fPIC选项,-fPIC是告诉gcc生成一个与位置无关的代码2gcc链接的时候要加-shared选项,意思是生成一个so共享库。对于linux或者unix,一个so文件,文件扩展名必须是so,文件名的前三个字母必须是lib 4.7.4 linux使用sogcc链接的时候需要加-L. 代表从当前目录下找相关的so文件,-l文件名(但不包括文件名开头的lib和扩展名so)例如编译一个main.o文件,要用到当前目录下的liba.so库gcc –o main.out –L. –la main.o 4.7.5 配置profile文件可以在当前目录下查找so文件linux不在当前目录下寻找可执行程序,同时也不早当前目录下找so库文件修改用户配置文件的方法1cd2vi .bash_profile3export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:.4保存退出5. .bash_profile 4.8 作业描述int sum1(int n);//n = 100,1,2,3,4,5,6,7,8,9,10的和要求不可以用循环,只可以用递归int sum2(int n);//n = 10从0到n范围内所有素数的和要求不可以用循环,只可以用递归5 指针重点:*****5.1 指针5.1.1 指针的概念指针也是一个变量,做为指针变量的值是另一个变量的地址。指针存放的内容是一个地址,该地址指向一块内存空间5.1.2 指针变量的定义可以定义一个指向一个变量的指针变量。int *p;//表示定义一个指针变量。*p;//代表指针所指内存的实际数据切记,指针变量只能存放地址,不能将一个int型变量直接赋值给一个指针。int *p = 100;5.1.3 NULL一个指向NULL的指针,我们称之为空指针,意味着这个指针不指向任何一个变量。5.1.4 野指针定义之后没有初始化值的指针file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE18.tmp.jpg 5.1.5 &取地址运算符file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE19.tmp.jpg 5.1.6 无类型指针定义一个指针变量,但不指定它指向具体哪种数据类型。可以通过强制转化将void *转化为其他类型指针,也可以用(void *)将其他类型指针强制转化为void类型指针。void *p在C语言当中,可以将任何一种地址赋值给void *指针5.1.7 指针的兼容性指针之间赋值比普通数据类型赋值检查更为严格,例如:不可以把一个double *赋值给int * 5.1.8 指针与数组的关系一个变量有地址,一个数组包含若干个元素,每个元素在内存中都有地址。int a;int *p = a;比较p和&a的地址是否相同 在C语言当中数组的名称代表数组的首地址,如果取数组名称的地址,C语言认为就是取数组的首地址。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE1A.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE1B.tmp.jpg 5.1.9 通过指针使用数组元素通过指针计算,不是把指针当做一个整数,计算结果,而是指针在内存当中移动p + 1代表&a,也可以直接使用p表示ap + 5 代表&ap++在C语言里面数组名称是个常量,值是不可改变的5.1.10 指针数组int *p;file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE2B.tmp.jpg 5.1.11 数组指针int (*P);file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE2C.tmp.jpg 5.1.12 指向指针的指针(二级指针)指针就是一个变量,既然是变量就也存在内存地址,所以可以定义一个指向指针的指针。    int i = 10;    int *p1 = &i;    int **p2 = &p1;    printf("%d\n", **p2);以此类推可以定义3级甚至多级指针。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE2D.tmp.jpg 5.1.13 指针变量做为函数的参数函数的参数可以是指针类型。,它的作用是将一个变量的地址传送给另一个函数。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE2E.tmp.jpg 5.1.14 一维数组名作为函数参数当数组名作为函数参数时,C语言将数组名解释为指针当数组名作为函数参数传递给被调用函数时,被调用函数是不知道数组有多少元素的 int func(int array);相当于传递是一个地址,那么就可以通过地址来修改实参的值。只要传递是数组名,那么形参一定可以通过地址修改实参的值。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE2F.tmp.jpg 5.1.15 二维数组名作为函数参数二维数组做函数参数时可以不指定第一个下标。int func(int array[]);5.1.16 指向二维数组的指针int a
a二维数组名称,数组首地址
a, *(a + 0), *a0行,0列元素地址
a + 1第1行首地址
a, *(a + 1)第1行,0列元素地址
a + 2, *(a + 1) + 2, &a第1行,2列元素地址
*(a + 2), *(*(a + 1) + 2), a第1行,2列元素的值
5.1.17 指向常量的指针与指针常量const char *p;//定义一个指向常量的指针char *const p;//定义一个指针常量,一旦初始化之后其内容不可改变5.1.18 const关键字保护数组内容如果将一个数组做为函数的形参传递,那么数组内容可以在被调用函数内部修改,有时候不希望这样的事情发生,所以要对形参采用const参数func(const int array[])5.1.19 指针做为函数的返回值char *func();//返回值为char *类型的函数5.1.20 指向函数的指针指针可以指向变量,数组,也可以指向一个函数。一个函数在编译的时候会分配一个入口地址,这个入口地址就是函数的指针,函数名称就代表函数的入口地址。函数指针的定义方式:int (*p)(int);//定义了一个指向int func(int n)类型函数地址的指针。1定义函数指针变量的形式为:函数返回类型(*指针变量名称)(参数列表)2函数可以通过函数指针调用3int( * P)()代表指向一个函数,但不是固定哪一个函数。
void man(){        printf("抽烟\n");        printf("喝酒\n");        printf("打牌\n");} void woman(){        printf("化妆\n");        printf("逛街\n");        printf("网购\n");} int main(){        void(*p)();        int i = 0;        scanf("%d", &i);        if (i == 0)                p = man;        else                p = woman;        p();        return 0;}
5.1.21 把指向函数的指针做为函数的参数将函数指针做为另一个函数的参数称为回调函数
int max(int a, int b){        if (a > b)                return a;        else                return b;} int add(int a, int b){        return a + b;} void func(int(*p)(int, int), int a, int b){        int res = p(a, b);        printf("%d\n", res); } int main(){        inti = 0;        scanf("%d", &i);        if (i == 0)                func(max, 10, 20);        else                func(add, 10, 20);        return 0;}
5.1.22 指针运算赋值:int *p = &a;求值:int I = *p;取指针地址 int **pp = &p;将一个整数加(减)给指针:p + 3; p – 3;增加(减少)指针值 p++,p--求差值 ,p1 – p2,通常用于同一个数组内求两个元素之间的距离比较 p1 == p2,通常用来比较两个指针是否指向同一个位置。 5.1.23 指针小结
定义说明
Inti定义整形变量
int *p定义一个指向int的指针变量
Int a定义一个int数组
Int *p定义一个指针数组,其中每个数组元素指向一个int型变量的地址
Int func()定义一个函数,返回值为int型
Int *func()定义一个函数,返回值为int *型
Int (*p)()定义一个指向函数的指针,函数的原型为无参数,返回值为int
Int **p定义一个指向int的指针的指针,二级指针
6 字符指针与字符串重点:****6.1 指针和字符串在C语言当中,大多数字符串操作其实就是指针操作。
char s[] = "hello word";char *p = s;p = 'a';
6.2 通过指针访问字符串数组 6.3 函数的参数为char *file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE5F.tmp.jpg 6.4 指针数组做为main函数的形参int main(int argc, char *argv[]); 作业//不可以使用任何C语言库函数,只可以自己写函数实现int 到字符串的转化void itoa(int i, char *s){}file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE60.tmp.jpg 7 内存管理重点:*****7.1 作用域一个C语言变量的作用域可以是代码块 作用域,函数作用域或者文件作用域。代码块是{}之间的一段代码。7.1.1 auto自动变量一般情况下代码块内部定义的变量都是自动变量。当然也可以显示的使用aotu关键字7.1.2 register寄存器变量通常变量在内存当中,如果能把变量放到CPU的寄存器里面,代码执行效率会更高register int I;7.1.3 代码块作用域的静态变量静态变量是指内存位置在程序执行期间一直不改变的变量,一个代码块内部的静态变量只能被这个代码块内部访问。7.1.4 代码块作用域外的静态变量代码块之外的静态变量在程序执行期间一直存在,但只能被定义这个变量的文件访问7.1.5 全局变量全局变量的存储方式和静态变量相同,但可以被多个文件访问7.1.6 外部变量与extern关键字extern int I;7.1.7 全局函数和静态函数在C语言中函数默认都是全局的,使用关键字static可以将函数声明为静态7.2 内存四区file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE61.tmp.jpg 7.2.1 代码区 代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的。 7.2.2 静态区所有的全局变量以及程序中的静态变量都存储到静态区,比较如下两段代码的区别
        int a = 0;        int main()        {                static int b = 0;                printf("%p, %p\n", &a, &b);                return 0;        }        int a = 0;        static int b = 0;        int main()        {                printf("%p, %p\n", &a, &b);                return 0;        }
7.2.3 栈区栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE72.tmp.jpg 7.2.4 堆区堆heap和栈一样,也是一种在程序运行过程中可以随时修改的内存区域,但没有栈那样先进后出的顺序。堆是一个大容器,它的容量要远远大于栈,但是在C语言中,堆内存空间的申请和释放需要手动通过代码来完成。 7.3 堆的分配和释放7.3.1 mallocfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE73.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE74.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE75.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE76.tmp.jpg 7.3.2 free 7.3.3 calloc:第一个参数是所需内存单元数量,第二个参数是每个内存单元的大小(单位:字节),calloc自动将分配的内存置0
int *p = (int *)calloc(100, sizeof(int));//分配100个int
7.3.4 realloc重新 分配大小。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE77.tmp.jpg 在C语言当中,内存初始化是个好习惯,除了全局变量和静态变量以外,其他变量C语言编译不会帮你初始化,只有自己通过显示的初始化。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE87.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsAE88.tmp.jpg

Minhal 发表于 2016-8-15 20:41:46

本帖最后由 Minhal 于 2016-8-15 20:49 编辑

这里的1是指第15章以此类推

1 结构体,联合体,枚举与typedef重点:****1.1 结构体1.1.1 定义结构体struct和初始化
struct man{        char name;        int age;};struct man m = { "tom", 12 };struct man m = { .name = "tom", .age = 12 };
1.1.2 访问结构体成员.操作符1.1.3 结构体的内存对齐模式结构在内存的大小是和结构成员最长的那个元素相关的编译器在编译一个结构的时候采用内存对齐模式
        struct man{                char a;                int b;        };
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7EE1.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F01.tmp.jpg 1.1.4 指定结构体元素的位字段定义一个结构体的时候可以指定具体元素的位长
        struct test{                char a : 2;//指定元素为2位长,不是2个字节长        };
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F02.tmp.jpg 1.1.5 结构数组
struct man m = { { "tom", 12 }, { "marry", 10 }, { "jack", 9 } };
1.1.6 嵌套结构一个结构的成员还可以是另一个结构类型
        struct names{                char first;                char last;        };         struct man{                struct names name;                int age;        };        struct man m = { { "wang", "wu" }, 20 };
1.1.7 结构体的赋值struct name a = b;结构的赋值其实就是两个结构内存的拷贝如果结构体成员有指针元素,那么就不能直接赋值,1.1.8 指向结构体的指针–>操作符1.1.9 指向结构体数组的指针 1.1.10 结构中的数组成员和指针成员一个结构中可以有数组成员,也可以有指针成员,如果是指针成员结构体成员在初始化和赋值的时候就需要提前为指针成员分配内存。
struct man{        char name;        int age;};
struct man{        char *name;        int age;};
1.1.11 在堆中创建的结构体如果结构体有指针类型成员,同时结构体在堆中创建,那么释放堆中的结构体之前需要提前释放结构体中的指针成员指向的内存。
struct man{        char *name;        int age;};        struct man *s = malloc(sizeof(struct man) * 2);        s.name = malloc(10 * sizeof(char));        s.name = malloc(10 * sizeof(char));
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F03.tmp.jpg 1.1.12 将结构作为函数参数将结构作为函数参数将结构指针作为函数参数 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F14.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F15.tmp.jpg 1.1.13 结构,还是指向结构的指针在定义一个和结构有关的函数,到底是使用结构,还是结构的指针?指针作为参数,只需要传递一个地址,所以代码效率高如果一个结构体变量做为函数的参数,效率极低。同时老的C编译器都不支持传递结构变量,只支持传递结构指针。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F16.tmp.jpg 1.1.14 远指针与近指针 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F17.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F28.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F29.tmp.jpg 1.2 联合体联合union是一个能在同一个存储空间存储不同类型数据的类型。联合体所占的内存长度等于其最长成员的长度,也有叫做共用体。联合体虽然可以有多个成员,但同一时间只能存放其中一种。对于联合体来讲最基本的原则是,一次只操作一个成员变量,如果这个变量是指针,那么一定是处理完指针对应的内存之后再来使用其他成员。
        union variant{                int ivalue;                char cvalue;                double dvalue;        };         int main()        {                union variant var;                var.cvalue = 12;                printf("%d\n", var.ivalue);                printf("%p, %p, %p\n", &(var.cvalue), &(var.ivalue), &(var.dvalue));                return 0;        }
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F2A.tmp.jpg 1.3 枚举类型1.3.1 枚举定义可以使用枚举(enumerated type)声明代表整数常量的符号名称,关键字enum创建一个新的枚举类型。实际上,enum常量是int类型的。枚举的本质就是int型的常量。
        enum spectrum { red, yellow, green, blue, white, black };        enum spectrum color;        color = black;        if (color != red)
1.3.2 默认值默认时,枚举列表中的常量被指定为0,1,2等
        enum spectrum { red, yellow, green, blue, white, black };        printf("%d, %d\n", red, black);
指定值可以指定枚举中具体元素的值
        enum spectrum { red = 10, yellow = 20, green, blue, white, black };        printf("%d, %d\n", red, black);
1.4 typedeftypedef是一种高级数据特性,它能使某一类型创建自己的名字
typedef unsigned char BYTE
1与#define不同,typedef仅限于数据类型,而不是能是表达式或具体的值2typedef是编译器处理的,而不是预编译指令3typedef比#define更灵活直接看typedef好像没什么用处,使用BYTE定义一个unsigned char。使用typedef可以增加程序的可移植性。1.5 通过typedef定义函数指针
typedef const char *(*SUBSTR)(const char *, const char *);const char *getsubstr(const char *src, const char *str){        return strstr(src, str);}const char *func(const char *(*s)(const char *, const char *), const char *src, const char *str)
const char *(*p)(const char *, const char *);
在程序当中如果是定义一个可读的常量,适合用#define如果定义的是一个具体的数据类型,那么typedef更加适合。如果是定义一个函数指针,那么基本就typedef吧. 2 文件操作重点:***不论操作什么类型的文件,第一步先打开一个文件,第二步,读写文件,第三步关闭文件。 2.1 fopenr 以只读方式打开文件,该文件必须存在。r+ 以可读写方式打开文件,该文件必须存在。用r+写文件时候,从文件开始位置写入rb+ 读写打开一个二进制文件,允许读写数据,文件必须存在。rw+ 读写打开一个文本文件,允许读和写。w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。wbw+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留),如果文件不存在,a的行为和w是一样的a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)“b”只对windows有效,对于unix来讲是无效,2.2 二进制和文本模式的区别1.在windows系统中,文本模式下,文件以"\r\n"代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n" 。2.在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。对于GBK编码的汉字,一个汉字两个字节,对于utf8来讲一个汉字3个字节,但如果英文字母都是一个字节2.3 fclosefclose关闭fopen打开的文件2.4 getc和putc函数
int main(){        FILE *fp = fopen("a.txt", "r");        char c;        while ((c = getc(fp)) != EOF)        {                printf("%c", c);        }        fclose(fp);        return 0;}int main(){        FILE *fp = fopen("a.txt", "w");        const char *s = "hello world";        int i;        for (i = 0; i < strlen(s); i++)        {                putc(s, fp);        }        fclose(fp);        return 0;}
2.5 EOF与feof函数文件结尾程序怎么才能知道是否已经到达文件结尾了呢?EOF代表文件结尾如果已经是文件尾,feof函数返回true。2.6 fprintf,fscanf,fgets,fputs函数这些函数都是通过FILE *来对文件进行读写。fscanf不会读取行尾的’\n’,fgets 会将行尾的’\n’读取到buf里面不论fprintf还是fputs都不会自动向行尾添加\n,需要代码中往buf的行尾写\n才可以达到换行的目录2.7 stat函数#include <sys/stat.h>函数的第一个参数代表文件名,第二个参数是struct stat结构。得到文件的属性,包括文件建立时间,文件大小等信息。2.8 fseek函数函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere为基准,偏移offset(指针偏移量)个字节的位置,函数返回0。如果执行失败则不改变stream指向的位置,函数返回一个非0值。实验得出,超出文件末尾位置,还是返回0。往回偏移超出首位置,还是返回0,请小心使用。第二个参数负数代表向前移动,整数代表向后移动。第一个参数stream为文件指针第二个参数offset为偏移量,单位:字节,正数表示正向偏移,负数表示负向偏移第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SETSEEK_SET: 文件开头SEEK_CUR: 当前位置SEEK_END: 文件结尾
fseek(fp, 3, SEEK_SET);
2.9 ftell函数函数 ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数。在随机方式存取文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置。
long len = ftell(fp)
2.10 fgetpos,fsetpos函数fseek与ftell返回的是long类型,如果文件很大,超过long的范围,那么该函数会有问题,fgetpos与fsetpos函数可以处理更大的文件类型返回值:成功返回0,否则返回非0
        fpos_t ps = 0;        fgetpos(fp, &ps);        fpos_t ps = 2;        fsetpos(fp, &ps);
2.11 fflush函数fflush函数可以将缓冲区中任何未写入的数据写入文件中。修改配置文件,希望修改实时生效,那么每次修改完成之后我们fflush一次file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F4A.tmp.jpg 2.12 fread和fwrite函数size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);注意:这个函数以二进制形式对文件进行操作,不局限于文本文件返回值:返回实际写入或读取的数据块数目只要读取到文件最后,没有完整的读取一个数据块出来,fread就返回0第一个参数代表void *,写入或者读取的缓冲区第二个参数是代表写入或读取的时候一个单位的大小第三个参数是代表写入或读取几个单位第四个参数是FILE * 2.13 fread与feoffile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F4B.tmp.jpg 注意以下两段代码的区别
        while (!feof(p))        {                fread(&buf, 1, sizeof(buf), p);        }
while (fread(&buf, 1, sizeof(buf), p))
2.14 作业有一个文本a.txt,内容一行是一个数字有多少随机的要求你写程序读取a.txt,将文件内容小到大排序,写入b.txt3 基础数据结构与算法重点:****,如果基础数据结构还不扎实的话,建议这段时间仔细的复习一下。3.1 什么是数据结构数据(data)是对客观事物符号表示,在计算机中是指所有能输入的计算机并被计算机程序处理的数据总称。数据元素(data element)是数据的基本单位,在计算机中通常做为一个整体进行处理。数据对象(data object)是性质相同的数据元素的集合,是数据的一个子集。数据结构(data structure)是相互之间存在一种或多种特定关系的数据元素的集合。数据类型(data type)是和数据结构密切关系的一个概念,在计算机语言中,每个变量、常量或者表达式都有一个所属的数据类型。抽象数据类型(abstract data type ADT)是指一个数据模型以及定义在该模型上的一组操作,抽象数据类型的定义仅取决于它的一组逻辑性,与其在计算机内部如何表示以及实现无关。3.2 什么是算法算法是对特定问题求解的一种描述,它是指令的有限序列,其每一条指令表示一个或多个操作,算法还有以下特性:Ø 有穷性一个算法必须总是在执行有限步骤后的结果,而且每一步都可以在有限时间内完成。Ø 确定性算法中每一条指令都有确切的含义,读者理解时不会产生二义性,在任何条件下,算法只有唯一的一条执行路径,即相同的输入只能得出相同的输出。Ø 可行性一个算法是可行的,即算法中描述的操作都是可以通过已经实现的基本运算来实现的。Ø 输入一个算法有零个或者多个输入,这些输入取自与某个特定对象的集合。Ø 输出一个算法有一个或多个输出,这些输出是和输入有某些特定关系的量。 3.3 链表3.3.1 单向链表定义对于数组,逻辑关系上相邻的连个元素的物理位置也是相邻的,这种结构的优点是可以随机存储任意位置的元素,但缺点是如果从数组中间删除或插入元素时候,需要大量移动元素,效率不高。数组的优缺点file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F4C.tmp.jpg 链式存储结构的特点,元素的存储单元可以是连续的,也可以是不连续的,因此为了表示每个元素a,与其接后的元素a+1之间的关系,对于元素a,除了存储其本身信息外,还需要存储一个指示其接后元素的位置。这两部分数据成为结点(node)。一个结点中存储的数据元素被成为数据域。存储接后存储位置的域叫做指针域。n个结点(ai(1<=i<=n)的存储映像链接成一个链表。整个链表必须从头结点开始进行,头结点的指针指向下一个结点的位置,最后一个结点的指针指向NULL。在链表中,通过指向接后结点位置的指针实现将链表中每个结点“链”到一起。链表中第一个结点称之为头结点。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7F4D.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7FAC.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7FAD.tmp.jpg 3.3.2 单向链表数据结构定义
struct list{        int data;//链表数据域        struct list *next;//链表指针域};
3.3.3 单向链表的实现
struct list *create_list()//建立一个节点void traverse(struct list *ls)//循环遍历链表struct list *insert_list(struct list *ls, int n, int data)//在指定位置插入元素int delete_list(struct list *ls, int n)//删除指定位置元素int count_list(struct list *ls)//返回链表元素个数void clear_list(struct list *ls)//清空链表,只保留首节点int empty_list(struct list *ls)//返回链表是否为空struct list *locale_list(struct list *ls, int n)//返回链表指定位置的节点struct list *elem_locale(struct list *ls, int data)//返回数据域等于data的节点int elem_pos(struct list *ls, int data)//返回数据域等于data的节点位置struct list *last_list(struct list *ls)//得到链表最后一个节点void merge_list(struct list *st1, struct list *ls2)//合并两个链表,结果放入st1中void reverse(struct list *ls)//链表逆置
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7FBD.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7FBE.tmp.jpg 删除元素操作file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7FBF.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7FC0.tmp.jpg file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7FC1.tmp.jpg 逆置链表-方式1,移动指针域file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7FD2.tmp.jpg 逆置链表-方式2,移动数据域 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7FD3.tmp.jpg 逆置操作1. 判断首节点的next是否为NULL;2. 判断首节点next的next是否为空,如果为空证明链表除首节点之外只有一个节点,所以不需要逆置;3. 定义一个指针last,指向首节点的next域,因为逆置之后,该域为链表尾节点;4. 定义三个指针,分别代表前一个节点,当前节点,下一个节点;5. 前节点指向链表首节点;6. 当前节点指向链表首节点的next域;7. 下一个节点为NULL;8. 循环条件判断当前节点是否为NULL,如果为NULL退出循环;a) 下一个节点指向当前节点的下一个节点;b) 当前节点的下一个节点指向前一个节点;c) 前一个节点指向当前节点;d) 当前节点指向下一个节点;9. 循环完成;10. 设置last节点的next为NULL;11. 设置链表首节点的next为前一个节点。3.4 查找3.4.1 顺序查找顺序查找的过程为:从表的最后一个记录开始,逐个进行记录的关键字和给定值比较,如果某个记录的关键字与给定值相等,则查找成功,反之则表明表中没有所查找记录,查找失败。3.4.2 二分查找在一个已经排序的顺序表中查找,可以使用二分查找来实现。二分查找的过程是:先确定待查记录所在的范围(区间),然后逐步缩小查找范围,直到找到或者找不到该记录为止。假设指针low和high分别指示待查找的范围下届和上届,指针mid指示区间的中间值,即 mid=(low+ high) / 2。 3.5 排序3.5.1 冒泡排序冒泡排序首先将一个记录的关键字和第二个记录的关键字进行比较,如果为逆序(elem > elem),则两个记录交换之,然后比较第二个记录和第三个记录的关键字,以此类推,直到第n-1个记录和第n个记录的关键字进行过比较为止。上述过程称作第一次冒泡排序,其结果是将关键字最大的记录被安排到最后一个记录的位置上。然后进行第二次冒泡排序,对前n-1个记录进行同样操作,其结果是使关键字第二大记录被安置到第n-1位置上。直到将所有记录都完成冒泡排序为止。 3.5.2 选择排序选择排序是每一次在n – I + 1(i=1,2,…n)个记录中选取关键字,最小的记录作为有序序列中第i个记录。通过n-i次关键字间的比较,从n-i+1个记录中选取出关键字最小的记录,并 和第i(1<=i<=n)个记录交换之。




人要学习6 发表于 2016-8-15 22:39:05

多大的速度速度速度

cosmosh73 发表于 2016-8-16 00:26:49

不错

樱花 发表于 2016-8-16 06:46:33

新手观看

lim1130 发表于 2016-8-16 07:32:17

{:5_98:}

miss陈 发表于 2016-8-16 08:05:53

想看看~

清风云雨100 发表于 2016-8-17 14:42:52

支持一下

千亩计者 发表于 2016-8-18 02:29:08

{:7_113:}

wl9970 发表于 2016-8-19 10:28:20

想好好学习学习

heblhc 发表于 2016-8-19 10:32:13

进来看看

陈乾坤 发表于 2016-10-22 21:57:13

1111111111

帝昊羽 发表于 2016-10-22 22:40:33

支持支持,好有用啊{:10_256:}{:10_256:}

求道于盲 发表于 2016-10-24 01:30:34

看看

穹星1412 发表于 2016-10-24 17:54:16

看看,大神,鱼油经过

qwe1231069 发表于 2016-10-24 21:42:02

感谢楼主分享

qxfsy 发表于 2016-10-25 18:12:31

谢谢啊!!!!!!!
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: C基础班讲义(新手老手都可以来看)