一、基本符号
- /n为换行符
- .h为头文件
- .c源程序文件,.exe可执行文件
- //为本行注释
- /**/为全部注释
- 转义字符:',",\,\a警告,\b退格,\f换页,\r回车,\t水平制表,\v垂直制表,\0,\00八进制对应ASCAII,\xh16进制ASCAII
二、符号的相关
- main函数执行错误时返回非0整数,可以根据返回值来判断程序是否正常运行
- scanf从键盘读取两个整数,放到ab的地址,再把值赋给a和b
- 将符号定义成常量#define pi 3.14;
- const定义常变量
- ++i,--i(在使用前先变化)
- 不能写int a=b=c=3
- %7.2f 代表指定数据占七列,小数占两列,后一位进行四舍五入
- 在include的时候可以用尖括号或双引号都可以,用双引号的时候先在用户的当前目录寻找文件找不到的时候再按照标准方式寻找
- 用%5d表示输出数据占五列,在此五列区域的右侧
- scanf double类型的时候用%lf
- %i与d的相同,o以八进制整型输出,x以十六进制整型输出,u无符号类型输出,g格式输出浮点数自动选择f或e,m代表一个正数的最小宽度,n代表正实数n位小数,对字符串表截取的个数,—靠左
- break只能用于循环或switch不能单独使用
- const为修饰符用来表达变量不变的属性,修改变量会发生错误
- 在if、else的后面必加上大括号形成块状语句,括号内缩进一个tab位
- 每次召唤rand()就可以得到一个随机的整数
- sizeof一个运算符,给出某个类型或变量在内存中所占字节数
- malloc申请空间以字节为单位返回的申请空间的首地址
- (int*)malloc(n×sizeof(int))
- 格式字符*的作用是表示指定的输入项在读入后不赋给相应的变量,%d星号%d,后一个数据不会被读入
三、函数
-
只有通过return语句才能把求出的z值作为函数值传递出来返回到调用他的main函数中,必须用return进行指定,不要不加分析将所有的函数值后面都加上return 0; -
函数的一般形式 int (函数类型) max(函数名) (int x,int y)(形参的类型和名称) -
如果函数没有参数,可在后面括号中写上void,也可以为空括号 -
void dump (){}为一个空函数是合法的 -
switch(表达式){ case 常量1;语句1;break; ······ default; 语句n+1;} -
定义函数的时候指定的函数类型应该和return中的表达类型一样 -
函数类型决定返回值的类型 -
函数的嵌套调用,可以在一个函数中调用另一个函数,但不可以在一个函数中定义另一个函数 -
函数的递归调用:间接或直接调用本身 -
一个函数只能被本文件中的其他函数调用称为内部函数,在定义函数时前面加上stastic其他文件不能引用 -
加extern为外部文件,定义函数时省略extern,默认为外部函数 -
定义函数后直接加{}不用加;声明后面需要有; -
abs()函数求整数的绝对值 -
labs求长整型的绝对值 -
fabs求浮点数的绝对值
四、一些相关知识
- 即使程序只有一个源程序文件,编译得到的目标也不能直接运行,要经过与函数库的连接,才生成可执行程序
- 算法的特性:有穷性,确定性,有0个或多个输入,有一个或多个输出,有效性
- 强制类型转换高于%
- x%=y+3相当于x%=(y+3)
- %20.5f小数也算作一位,所以前面有三个空格
- 全局变量与局部变量相同的时候局部变量会将全局变量屏蔽,全局变量仍然放在静态存储区中
- 局部变量都是动态分配存储空间的,函数的形参和函数中定义的局部变量都是,调用函数时系统会自动给这些变量分配存储空间,函数调用后释放,此类局部变量称为自动变量用auto存储类别声明
- 局部变量在调用函数后不消失,即占用的存储单元不释放,在下一次调用函数已有值,称为静态局部变量stastic,虽然他依旧存在,但其他函数不能调用它,因为他是局部变量只能被本函数引用
- 在定义点之前的函数不能引用变量,由于某种考虑,在定义点之前的函数要引用该外部变量,则在引用之前使用关键字extern对变量进行外部声明,表示把该变量的作用域扩展到此位,用extern声明变量的时候类型名可以写也可以不写
- 一个文件想引用另一个文件中已经定义的外部变量,两个文件用同一个外部变量不能分别在两个文件中各定义一个外部变量,否则会出现重复定义,应在任一文件中定义外部变量,在另一个文件中用extern进行连接
- 逻辑运算符的优先级为!非&&与||或
- a=(b>0)?b:-b当大于0的时候等于b小于0的时候等于-b
- a=(++b,c--,d+3);值为最后一个
- a=++b,c--,d+3;值为第一个
- 指针数组做main函数的参数int main(int argc,char* argv[ ])第一个形参必须是int型,第二个形参必须是字符指针数组,用来接收从操作系统命令行传来的字符串中首字符的地址,在许多操作命令状态下,命令行中包括了命令和传递给main的参数
- filel(命令名)china(形参1)beijing(形参2)
- 文件名应该包括盘符、路径、简化起见用file表示
- argc为行中参数的个数,文件名也作为一个参数
- argv是一个指向字符串的指针数组,命令参数必须是字符串,首地址构成一个指针数组
- 动态存储区称为栈,动态分配区域存放临时数据,需要时随时开辟,不需要的时候随时释放,放在一个特别的自由存储区,称为堆区
- 由于未在声明的部分定义他们为变量或数组,因此不能通过变量名或数组名去引用,只能通过指针来引用
- 使用malloc的时候应加头文件stdlib.h
五、变量
- 常量:整型,字符型,实型
- 变量名实际上是以一个名字代表一个存储地址,对程序编译连接时由编译系统给每个变量分配对应的内存地址。从变量中取值,实际上是通过变量名找到对应的内存地址,从该存储单元中读取数据
- 标识符只能为字母、数字、下划线组成,且第一个不能为数字
- 求负数的补码:将对应的正数写为二进制,按位取反再加一
- 存放整数的存储单元中,最左位用来表示符号,0为正,1为负
- 要求长整型不低于int型,短整型不长于int型2、4、4、8
- %u表示无符号十进制的格式输出
- ASCAII包括127个字符字母AZ,az,数字0~9,29个专门符号。最多用7个二进制位就可以表示
- C是字符变量,实质为一字节的整型
- 由于小数点的位置可以浮动,实数的指数形式为浮点数
- 在存储时,系统将实型数据分成小数部分和整数部分分别存放float 8,double 8,long double 8 16,编译系统将浮点型都看作双精度进行处理,分配八个字节
- 整数在0~127的范围中可用%c对对应的字符进行输出
- float有6~7位小数,double有15位小数
- 实数在计算和存储的时候会有一些微小的误差,不能用if(a==0)判断,会出现原本为0的量由于上述误差而被判别为不为0
- 表达数的范围char>short>int>float>double
六、字符类型
- putchar(c) c为字符变量、字符常量、整型变量、整型常量
- 字符先暂存在键盘的缓冲器中,按下enter键的时候把字符输入到计算器中
- printf("%s\n",c)c是已定义的字符数组名
- scanf("%s",c)
- 系统将空格字符作为输入字符串之间的分隔符
- puts函数输出的字符串可以包含转义字符
- puts(字符数组)
- strcpy自左向右逐渐比较按ASCAII码值出现不同的以第一对为准同为0,大于为正,小于为负
- 对于字符串的比较,不能用if(str1>str2),只代表地址不能代表数组中的全部元素
- strlen()测试字符串长度
- strlwr()将字符串中的大写字母转换为小写字母
- strupr()转换为大写
- return z与return (z)等价,return后面可以是表达式
- 安全输入字符串char string[8];scanf("%7s",string);
- char line[]="hellow" strlen(line)=5 sizeof(line)=6
- 只有字符变量没有字符串变量
- 大写字符和小写字符的ASCAII值相差32
- char a[100];gets(a);
七、数组
- int a[n]不合法,不允许对数组的大小进行动态定义
- 二维数组的一维长度可以省略,但二维不可以
- 内存中各元素不是二维的是线性连续的
- printf("%o",c)用八进制输出字符数组的起始地址
- int a[0]可以存在
- int a[10]={[0]=2,[2]=3,6}
八、指针
-
定义指针int* pointer_1=&a -
两个指针变量互换后他们原来指向的变量的值不变,只是存储他们的位置改变了,当指针作为函数的参数的时候,互换可以将值带出(可用于将函数中的多个值带出) -
由于单向传送的值传递方式,形参改变不能使实参改变 -
数组元素的指针就是数组元素的地址 -
int a[10]={1,2,3,4}; int* p; p=&a[0]或p=a; -
[ ]为变址运算符,首地址加上里面的偏移地址来找到对应值所在的位置,可以对数组做也可以对指针做 -
p2-p1=2同一数组指针的减法,但是相加的是无意义的 -
数组的名代表数组首元素的地址,他是一个指针型常量,++操作并不能改变值 -
++操作与*同一优先级,结合方向从右向左,等价于先应用指针再进行加加操作 -
a+i与*(a+i)无条件等价 -
二维数组中a[0]与*(a+0)等价 -
二维数组a有关的指针 a 二维数组名,指向一维数组a[0],0行的起始地址 a[0]、*(a+0)、*a 0行0列元素的起始地址 a+1、&a[1] 1行的起始地址 a[1]、*(a+1) 1行0列元素a[1][0]的地址 a[1]+2、*(a+1)+2、&a[1][2] 1行二列a[1][2]的地址 -
指向二维数组的指针变量 int a[3][4]={1,2,3,4,5}; int (*p)[4]; p=a; -
total*=sum+12 等价于total=total*(sum+12) -
void search (float(*p)[4],int x);指向一维数组score[0] search(score,n) void average(float*p,int x);指向float型 score[0][0] -
对于字符常量是按照字符数组处理的,在内存中开辟了一个字符数组来存放该字符串常量,但字符数组没有名字,不能用数组名来进行引用 -
char* string; string="i love china" -
通过字符数组或字符指针变量可以输出一个字符串,对于整型数组不能企图用数组名输出全部元素,对于数组名的输出只能得到他的首地址 -
&*的优先级相同进行自右向左的的结合 -
字符指针做函数参数 void copy(char form[],char to[]); char a[]="I am a teacher"; char b[]="you are a student"; char* from=a; char* to=b; copy(from,to); -
字符数组由若干个元素组成,每个元素中放一个字符,而指针变量放的是地址,可以对字符指针变量赋值,但不能对数组名赋值char a[10];a="I love";是错误的 -
如果定义了一个字符指针变量,应及时把一个字符变量(或数组)的值赋给他,使他指向一个字符型数据,如果未对他赋予一个地址值,他并未具体指向一个确定的对象,此时对该指针变量指向的对象输入数据可能会出现严重的后果 char*a,str[10]; a=str; scanf("%s",a); 不能直接scanf ("%s",a) -
函数的指针,在程序中定义了一个函数,在编译时会将函数的源代码转换为可执行代码并分配一段存储空间。这段存储空间有一个起始地址,称为函数的入口地址。每次调用时都从该地址入口执行此段函数代码。函数名表示函数的起始地址,调用函数时,从函数名得到起始地址,并执行代码,函数名代表函数指针,代表起始地址 -
int (*p)(int,int)p与函数名共同存放函数的起始地址 -
函数指针+1没有意义 -
(*p)相当于函数名 -
一个指针变量可以先后指向相同类型的不同函数 -
int max(int a); int min(int a); int (*p)(int a); p=max; -
在多应用程序中常用菜单提示输入一个数字,再根据输入的数字来调用不同的函数,实现不同的功能 -
用指向函数的指针作为函数的参数 int fun(int x,int y,int,(*p)(int,int)); -
返回指针型的函数 -
指针数组和多重指针,int* p[4]; [ ]优先级必*高 -
二维数组存放字符串时只能依据最长的一个来确定二维数组浪费空间,但应用指针数组使每个元素存放字符串的首地址就可以 -
if(星号name[k]>*name[i]);k=i判断不成立,只会比较字符串的第一个字符,字符串的比较要用strcmp函数 -
指向指针数据的指针变量char* name[ ]={"follow me","basic"}; char **p; int i; for(i=0;i<5;i++){ p=name+i; printf("%s\n",*p); }
九、一些技巧
- x%n的结果为[0,n-1]的一个整数
- 进行求和的程序时一般将记录结果的变量初始化为0,求积的时候则一般设为0
- 有固定次数用for,必执行一次的时候用do_while,其他的时候用while
- 多重循环嵌套时可专门设置一个参数值对此进行判断,满足某种条件就改变参数的值,后接break,跳出当前这层循环,后面的循环也对此值进行判断,如果改变就执行break,此变量需要在最外层循环定义的(接力break)
- goto用goto来标记需要从哪里跳出,后接一个变量例如out,在需要跳到的地方加out:
十、结构体
-
struct 结构体名 {成员列表} -
struct student { int num;
char name[20];
struct date birthday; -
定义结构体变量struct student student1,student2; -
struct student{……}student1,student2; -
结构体变量中的成员名可以与程序变量名相同,但二者不表示同一对象 -
结构体变量的初始化student1={……,……}; -
成员初始化struct student student1={.name="zhang"}; -
.是成员运算符 -
不能对整个变量进行读入操作 -
使用结构体数组 struct person{ char name[20]; int count;}leader[3]={"li",0,"zhang",0,"sun",0} -
指向结构体变量的指针 struct student* p; 用(*p).num来调用子成员可以用p→num来进行等价代替
十一、共用体
-
union 共用体名{成员列表}变量列表 -
union data { int i; char ch; float f; }a={1,'a',1.5}是不可以的因为这三个变量共同占有同一段内存 可以union data a={1} -
a.ch='a';a.f=1.5;a.i=40;最后放入到数值为40,用printf("%c",a.ch),输出的字符不是a而是c,是40的ASCAII值 -
c99允许同类共用体之间相互赋值
|