1.优先级
2.基本输入输出函数
putchar(a)、a=getchar()、printf、scanf(“%d”,&a);
3.格式字符串
%【标志】【输出最小宽度】【.精度】【长度】类型
不到最小宽度补空格
%02d 补0
%-2d 右补空格
4.标志:
- 左对齐
+ 输出符号
空格 正时空格,负时负号
# 输出前缀
5.输出表中求值顺序
turbo c 从右到左
printf(“%d\n%d\n”,c=a+b,a++);
6.scanf的一般格式
%【*】【输入数据宽度】【长度】类型
*表示读入但不赋给变量
例:scanf(“%d %*d %d”,&a,&b);
7.若输入字符中无非格式字符,则所有输入字符均为有效字符,包括空格
8.若输入字符中有非格式字符,则所有输入字符中也需要非格式字符。
9.运算符优先级由高到低:!、算数、关系、逻辑、条件(?:)、赋值
10.c语言中else总是和他前面的if配对。
11.单个赋值语句使用条件运算符比使用条件表达式更简洁
a=(b>c)?b:c;
12.赋值运算符和条件运算符的结合方向都是从右至左。
13.switch后面的case后面允许多个语句且不需要括号括起来。且case后面必须是常量表达式且不重复。
14.scanf必须从缓冲区读入一个非空字符再回车才会刷新缓冲区。
15.%f默认小数点后6位
16.逻辑运算符有从简现象。从左往右,可以确定表达式值时,就不会再进行运算。
17.一个break语句只跳出一层,且对if else无效
18.在c中要想打印一个字符串数组可以通过for循环或者将数组名赋给指针变量(即首地址给指针),然后通过printf指针来实现打印字符串。
19.数组名只代表首地址
20.c编译对数组不做越界检查。
21.数组名是地址常量。
22.数组初始化时,当初始化元素少于数组个数时,自动初始化0.
23.错误初始化:int a[5]={};
24.选择法和冒泡法的复杂度是一样的,但如果对冒泡法进行改进,即加入flag来判断某轮中是否进行了改变,从而是复杂度小于等于原来的复杂度。
25.二维数组:a[i][j]
26.c语言中二维数组按行排列。
27.二维数组可以进行分段和不分段赋值,分段:a[2][2]={{1,2},{3,4}};不可以出现空括号{}
28.二维数组第一维长度可省略,第二维长度不可省略。
29.字符数组可以通过字符串常量赋值也可以逐一赋值,与普通数组相对,初始化时(未初始化的不自动初始化)未给初值的自动初始化为‘\0’空字符,其ascii码值为0。
30.空格字符‘ ’和空字符‘’不一样,空格字符ascii码为32,以%c输出空字符时,会占一列,但不显示任何东西。
31.相同的字符串,用逐一赋值和字符串赋值会相差一个字节。
32.C语言没有字符串变量。
33.sizeof是数组长度,strlen是字符串长度。
34.字符数组中字符串的输出:printf(“%s”,地址);地址可以使数组名,输出时遇到第一个空字符‘\0’结束。
35.使用scanf读入字符串时,无法读入空格,可以使用gets。
36.string.h中包含的常用输出输入函数:puts(str);gets(str);gets只以回车作为字符串结束标志。
37.strcat(str1,str2);第一个参数必须是字符数组名
38.strcpy(str1,str2);第一个参数必须是字符数组名,copy时会把空字符一同复制
39.字符数组不能直接赋值。
40.strcmp(str1,str2);str1=str2 返回0,str1<str2返回负数,str1>str2返回正数,逐位比ascii码。
41.如果用字符串名直接比较,实际比较的是地址。
42.printf(“%d”,“abcdefg”+2);输出c所在内存单元的地址
43.printf(“%s”,“abcdefg”+2);输出cdefg
44.strlwr(str1)大写变小写,strupr(str1)小写变大写
45.for循环通不过判断不会执行自加函数。
46.不能用变量作为数组的长度。
47.一般用宏定义来表示数组长度。
48. \ddd | 1到3位,八进制数,所代表的任意字符 |
49. \xhh 1到2位16进制数所代表的任意字符
50. 如果要用isupper函数,需要<ctype.h>头文件。
51.c语言中调函数需要先进行函数定义,或者将定义直接放在调用函数之前。
52.形参必须给定类型说明,并且就算是一样类型的形参也必须一个一个单独说明类型。
53.函数定义的传统格式:
int max(a,b)
int a,b;
{
}
54.空函数用来占位。
55.函数调用只能返回一个函数值,可以有多个return,但只会执行一个return,且执行了return以后函数结束。
56.函数返回值的类型以函数类型为准,return后的类型会向函数类型转换。
57.不同系统,实参的求值顺序是不同的,同printf。尽量避免这种情况。
58.对函数声明是为了方便编译器的识别。
59.return的写法:return(a)或return a;
60.函数声明时不一定要形参的名字。
61.函数不可以嵌套定义,但可以嵌套调用。
62.直接或间接调用自身函数都叫递归调用,递归调运一般用条件判断来终止。
63.形参为数组名时:1.实参是地址(数组名、元素地址、指针),但类型必须一致。2.形参和实参所指内存单元一致,修改形参所指内容会改变实参所指内容。
64.二维数组作为形参变量时,至少要给出第二位的长度,不然调用的时候进行地址传递的时候,二维数组是行地址,形参无法确定除第一行外的行地址,所以无法传递地址。
65.当形参数组和实参数组的维数不一致时,编译可通过,但是结果可能有问题。
66.复合语句定义的变量,其作用域只在复合语句范围内。
67.在每一层里,要先做所有的声明,然后写执行语句。
68.在复合语句中的变量会覆盖外层的同名变量。
69.全局变量一般在头文件中用extern声明,并使用#ifndef _TOU_H_ \n #define _TOU_H_ \n....\n #endif然后在c文件中用include包含头文件再定义。
70.变量的属性有作用域和生存期。
71.变量按生存期分为auto、register、extern、static
72.自动变量只有在使用它时才会分配内存。
73.static定义的变量若未赋初值,则会自动赋初值0.
74.static修饰的全局变量只能在本文件中使用。
75.函数声明也分局部和全局。
76.register将变量存在寄存器中,现在没有多大必要。
77.i++=m+1;这种写法是错误的,不合法左值。
78.指针变量是存放指针的变量,变量的指针是一个变量的地址,编译后就不会改变。
79.(16位)指针变量占两个字节。(即四位16进制数),32位的占四个字节。
80.指针变量初始化时是通过地址来初始化的。
81.未经赋值的指针变量不能使用。
82.int a,*p=&a; int a[],*p=a; int *p="123456";
83.指针变量的加减以及自加自减都是相对元素类型而言的,不是单纯的地址加1减1.
84.int *p; p!=0;或(p!=NULL;表示空指针),0表示地址0,地址0不能用于读写;
85.*(指针)优秀级和--和++相同。
86.void型指针是无指定类型指针,将它的值赋给另一变量时要进行强制类型转换。
87.野指针即悬空指针很危险,最好赋初值时指向NULL。
88.二级指针:int **p 指向指针的指针。
89.sizeof(指针);vc++一只返回4,tuboc返回2
90.int a[10]; sizeof(a)返回40,sizeof(a+1)返回4,因为数组名不是单纯的首地址,它是一种保存了数组大小的结构。
91.指针变量占内存空间,可以变,数组名是指针常量不占内存空间,不能变。
92.使用指针法访问数组能使目标程序占用内存少且运行速度快,占用内存小因为不用新建变量分配内存,尤其是函数的输入参数。速度快是因为节省了分配内存的时间,在分配较大的内存空间时可能需要遍历内存,耗时。
93.对于二维数组a[3][3],a+1指的是第二行的首地址,即a[1],a是一个二级指针 *a为一级指针。
94.a[2][2]的0行0列元素首地址的等价形式:
a a[0] *a &a[0][0]
95.指向二维数组的指针变量的定义,int (*p)[5];
96.int (*p)(); p为指向int函数的指针变量。
97.函数名是函数的入口地址。
98.用指针调用函数的一般形式:(*指针变量名)(实参表);
99.指向函数的指针可以作为参数传递给其他函数。如果直接用函数名做参数,编译器无法识别究竟是变量还是函数
100.返回指针值的函数就是指针函数。
101.指针数组名实际上是二级指针。
102.指针数组的定义:类型标识符 *数组名[数组长度]。
103.可以用一个指针数组指向一个二维数组。
104.exit(0) 正常退出 exit(1) 发生错误后退出
105.main函数命令行参数表示形式:main(int argc,char *argv[]) argc是实际参数的个数,系统文件名也算一个参数,若有四个字符串,则argc=5。
106.结构体可以嵌套定义。
107.类型的定义和类型变量的定义是不同的,类型的定义是给编译器看的,不会产生可执行文件,重复也没有关系,所以将类型的定义放在.h文件中。类型变量一般在.h中声明,在.c中定义。
108.可以在定义结构类型时直接定义结构体变量
struct a
{
}a1,a2;
可以定义无名结构,但定义结构的同时要定义变量,不然没法用。但是如果定义无名结构时不给变量也不会报错。
109.结构体变量的成员都是通过成员运算符来访问的。
110.可以对结构体变量进行整体赋值。
111.可以构建结构体数组。
112.可以构建指向结构体的指针,如:struct stu{...}stu1; struct stu *p; p=&stu1;结构体变量名并不是结构体首地址
113.可以用三种方法去取结构体成员
1. 结构变量.成员名
2.(*结构指针变量).成员名
3. 结构指针变量->成员名
114.对结构体变量初始化时,可以部分初始化,未初始化的在末尾,且赋值0或‘\0’;
115.不能对结构体类型中的变量赋初值,如果结构体类型重定义了const int a;那在构建该结构体变量时必须给a赋初值。
在c中const int a=5;int b[a];会报错,c++中不报错。
116.指向结构数组的指针与指向一维数组的指针是一样的,这时候的数组名就是首地址。
117.结构体变量作函数参数,这种方式时间和空间开销很大,降低程序的效率。
118.结构指针变量或是指向结构体数组的指针作为函数参数,开销小,速度快。
119.数据结构分静态数据结构和动态数据结构,静态数据结构如数组、结构体等,动态数据结构最基本的就是链表和二叉树。
120.静态内存是栈分配的,动态内存是堆分配的。
121.栈用于存放函数的所有局部变量(auto类型),以及函数调用和返回的有关信息,它严格按照先进后出的规则管理栈中的数据。
122.malloc的用法:int *p=(int *)malloc(sizeof(int));分配的内存是连续的,如果内存不足,返回NULL。
123.必须使用指针变量接受malloc函数的返回值。
124.calloc与malloc的不同就在于分配了n块连续的内存空间,返回的是首地址。如ps=(struct stu*)calloc(2,sizeof(struct stu));
125.可以用free(void *ptr);释放用malloc和calloc分配的内存。
126.链表是动态数据结构中最简单的一种。
127.组成链表的每一个元素叫结点,结点由数据域和指针域组成。头指针即表头无数据,尾指针的指针域为NULL。
128.链表的节点的定义如下:
struct 结构名
{
数据成员列表;
stuct 结构名 *指针名;
};
129.创建链表:
1.表头插入法:新的结点不断插入表头,p->next=head;head=p;书上先判断表头是否为空,我觉得多此一举。
2.表尾插入法:表尾插入法还需要一个指针指向表尾。
3.插入中间结点需要两个指针来遍历链表,两个指针是前后关系,还需一个指针来插入新结点。
130.不能对共用变量初始化,不能共用变量作函数参数也不能返回共用变量,但可以用指向共用变量的指针。
131.共用变量的成员共享内存。
132.因为uion成员共用空间,所以定义union变量时,其内存大小取决于成员中所需内存最大的成员。
133.枚举类型是基本数据类型。
134.枚举类型的定义:enum 枚举标识符 {枚举元素表}
135.枚举元素是常量;枚举元素不能和其他变量同名;枚举元素不能进行赋值;枚举元素的值是顺序增加的;可以使用如下方式:enum days {a=1,b,c=4,d};元素值分别为a=1,b=2.c=4,d=5
136.结构体和共用体成员名和普通变量名是可以重复的。
137.只能将枚举元素赋给枚举变量,如果要赋0、1等数值时需要强制转换。
138.枚举元素的值可以重复。
139.枚举元素不占内存,类似宏定义,在预编译时就转换了。
140.typedef<类型><自定义类型名>
141.#define只是预编译时单纯的替换,typedef是编译时处理的,是通过检查的,
区别:#define pint int* const pint a;此时a是可改的,a指向的内容不可改。typedef int* pint; const pint a;这时a指针不可改,指向的内容可改;
142.c语言有三种预处理过程:宏定义、文件包含、条件编译 预处理是不做语法检查的。
143.C语言流程:编写c代码、预处理、编译、运行
144.字符串双引号内的内容永远不进行宏替换。
145.宏定义:#define #undef #ifndef #endif #ifdef #if #else
146.宏定义分有参和无参两种:有参的如下:
#define 宏名(参数表) 字符串 #define add(a,b) ((a)+(b))
147.宏嵌套:一个宏可以做另一个宏的参数;一个宏定义中使用另一个宏。
148.#include "" #include<> 双引号是在当前的源文件目录下查找文件,<>是在包含文件目录中查找
149.文件包含允许嵌套
150.条件编译的主要目的是解决软件兼容性和跨平台移植的问题。
如:#ifdef Win16
#define 。。。
#else
#define
#endif
151.宏的使用消耗了存储空间,函数消耗了时间(个人认为所谓的宏的使用消耗存储空间,消耗的是代码空间,代码也占内存,存放在代码段)
152.根据文件的保存内容可分为:程序文件和数据文件
153.根据文件的存储形式可分为:文本文件(ASCII)和二进制文件
154.文本文件需要花费转换时间,且占用存储空间较多。
155.文本根据其是否使用缓冲区可分为:标准文件和非标准文件
156.文本根据其存取方式可分为:顺序存取文件和直接存取文件
157.c语言中操作文件都是使用文件指针变量:FILE *变量名,FILE是stdio.h头文件中定义的结构体。
158.打开文件的方式:FILE *p=fopen(const char *filename,const char *mode); 正常打开返回0,错误返回NULL;
159.常用mode:“r”只读,“w”只写:指向文首部,“a”追加:指向文件尾,“rb”:打开只读二进制文件,“r+”以读写方式打开一个已存在的字符文件
“w+”以读写方式建立一个新的字符文件,“a+”为读写打开一个字符文件进行追加。还有“rb+”,"wb+","ab+"
160.为了增强程序的可靠性,常用下面的方法打开一个文件:
if((p=fopen("filename","mode"))==NULL)
{
printf("can not open this file\n");
exit(0);
}
161.每个文件至少都有一个文件结束标志EOF,它的值为-1,且它是一个宏。
162.关闭文件:fclose(文件指针);有返回值,0表示正常关闭。EOF表异常
163.c语言中可以使用fcloseall()关闭所有打开的文件:n=fcloseall();n为关闭文件的数目。
164.标准设备文件不需要再打开和关闭,系统自动定义了5个FILE结构指针变量。
键盘 stdin
(标准输出)显示器 stdout
异步串行口 stdaux
打印机 stdprn
(标准错误输出)显示器 stderr
165.单字符读函数 char fgetc(FILE *fp);如果成功,返回读入的字符,失败则返回EOF,想要知道是文件结束还是失败,可以调用feof()或ferror()进行检查。
166.单字符写函数 char fputc(char c,FILE *fp);同上,且这两个函数读写一个字符后,都会将文件指针指向下一个字符位置。
167.将文件内容输出到显示屏上:while((ch=fgetc(fp))!=EOF)fputc(ch,stdout);其实就是输出在命令窗口里。
168.二进制文件的后缀名为.bin
169.exit函数包含在<stdlib.h>中
170.ascii码:a:97 A:65 0:48
171.fgets(char *str,int n,FILE *fp); 读到n个字符或是遇到换行符或是EOF结束。将字符串赋给str时,会自动在末尾添加空字符‘\0’
172.数据块读写函数:
int fread(void *buff,int size,int count,FILE *fp);
int fwrite(void *buff,int size,int count,FILE *fp);
173.fread和fwrite成功则返回count
174.除fgets失败返回NULL,fgetc,fputc,fputs失败返回EOF;
175.fread和fwrite一般用于二进制文件的处理。
176.格式化读写函数fscanf()和fprintf()
177.fscanf(FILE *stream,char *format,<variablelist>);
fprintf(FILE *stream,char *format,<variablelist>);
178.传统二进制文件的后缀名为.bin
179.文件指针定位函数:rewind()、fseek()、ftell()
180.int fseek(FILE *fp,long offset,int whence);一般用于二进制文件
offset为偏移量,偏移量大于0向前,小于零向后,whence为起始位置 0:文件头,1:当前位置,2:文件尾
ANIS C标准中还规定了下面的名字:
SEEK_SET(0) --文件头
SEEK_CUR(1) --当前位置
SEEK_END(2) --文件尾
181.void rewind(FILE *fp);将文件位置指针重新返回文件开头;
182.文件指针位置查询函数:long ftell(FILE *fp);返回位置指针相对文件头的偏移量,若出错返回-1L
183.文件结束检测函数 int feof(FILE *fp),文件结束返回真,否则返回0.
184.文件出错检测函数int ferror(FILE *fp);使用方法:if(ferror(fp)){...} 注:fopen时会将ferror的值置0;
185.clearerr(FILE *fp);清除错误标志和文件结束标志,使它们为0,错误标志位会一直保留,指导使用clearerr()、rewind()、或是任意输入输出函数为止。
186.在关闭文件时,最好使用判断 if((fclose(fp))==EOF),fclose错误返回EOF
187.特别注意,C语言最好把变量定义放在函数之前,
188.使用free(p);p必须是首地址,如果程序中执行过类似p++的程序,请开始时保存首地址,或者退回到首地址。