C语言学习笔记悉心整理.docx
《C语言学习笔记悉心整理.docx》由会员分享,可在线阅读,更多相关《C语言学习笔记悉心整理.docx(31页珍藏版)》请在冰豆网上搜索。
![C语言学习笔记悉心整理.docx](https://file1.bdocx.com/fileroot1/2023-1/25/5f9db27e-91c5-4b6a-9c39-47eea013bcb0/5f9db27e-91c5-4b6a-9c39-47eea013bcb01.gif)
C语言学习笔记悉心整理
C语言程序基础
基本元素
若干函数构成C语言程序,必须有一个main函数
基本数据类型
整数:
int,shortint/short,longint/long.
实数:
float,double
字符:
char
类型
定义符
基本C中占的字节数
.NETC中占的字节数
整数
short
2
2
int
2
4
long
4
4
实数
float
4
4
double
8
8
字符
char
1
1
注意:
1,数据在计算机中的存放是以补码的形式存放,所以计算每个数据类型的取值范围时候要注意。
2,float的有效位数是7位,double的有效位数是16位
3,转义字符:
\n\t\b\r\\\’\”\ddd\xhh,转义字符定义一定要用这个形式。
4,char和int可以通用,当把字符赋值给整型变量时,采用符号扩展,把整数赋值给字符变量时,截取整数的低字节的值。
5,使用sizeof()函数可以获得变量所占的字节数
常量与变量
变量名用标示符表示,由字母数字下划线组成,必须是字母或者下划线开头。
变量必须先定义在使用:
类型标示符变量列表;
可采用的定义以及赋初始值的格式:
inta,b,c;
a=1,b=2,c=3;
或
inta=1,b=2,c=3;
可以用#define定义常量,例如#definePI3.1415926,一般常量用大写表示,变量小写
运算符和表达式
算术运算符和表达式:
+-*/%(模运算)
两个整数相除,结果一定是整数
模运算符(求余)要求两个运算对象必须是整数,结果的符号与被除数(分子)一致。
赋值运算符和表达式:
=
<变量>=<表达式>
顺序是自右到左。
复合赋值运算符:
+=-=*=/=%=<<=>>=&=^=|=
以+=为例:
a+=b等效于a=a+b;
结合顺序也是从右向左
强制类型转换符号
如:
(int)x;将该表达式的值强制转换成int型
自增、自减:
++--
++i,i++,--i,i—
++i先将i的值加1,再使用i
i++先使用i的值,再将i的值加1
例子:
k=(i++)+(++i)+(i++)等效于i=i+1,k=i+i+i,i=i+1,i=i+1
k=(++i)+(++i)+(++i)等效于i=i+1,i=i+1,i=i+1,k=i+i+i
逗号运算符:
“,”优先级最低的符号
形式:
表达式1,表达式2,……,表达式n
运算顺序,从左向右,最后最右边表达式n的值是整个逗号表达式的值
关系表达式及运算符
关系运算,结果只能是“真”或者“假”。
关系运算符
含义
优先级
<
6
<=
6
==
7
>
6
>=
6
!
=
7
逻辑运算
逻辑运算符&&与||有一些较为特殊的属性,由&&与||连接的表达式按从左到右的顺序进行求值,并且,在知道结果值为真或假后立即停止计算。
根据定义,在关系表达式或逻辑表达式中,如果关系为真,则表达式的结果值为数值1;如果为假,则结果值为数值0。
逻辑非运算符!
的作用是将非0操作数转换为0,将操作数0转换为1。
条件运算
在表达式expr1?
expr2:
expr3中,首先计算expr1,如果其值不等于0(为真),则计算expr2的值,并以该值作为条件表达式的值,否则计算expr3的值,并以该值作为条件表达式的值。
位运算
C语言提供了6个位操作运算符。
这些运算符只能作用于整型操作数,即只能作用于带符号或无符号char、short、int、long类型:
&按位与(AND)
|按位或(OR)
^按位异或(XOR)
<<左移
>>右移
~按位求反
运算符优先级与求值次序
()[]•>.从左至右
!
~++••+•*(type)sizeof从右至左
*/%从左至右
+•从左至右
<<>>从左至右
<<=>>=从左至右
==!
=从左至右
&从左至右
^从左至右
|从左至右
&&从左至右
||从左至右
:
从左至右
=+=•=*=/=%=&=^=|=<<=>>=从右至左
从右至左
一元运算符+、、&与*匕相应的二元运算符+、、&与*的优先级高。
顺序结构程序设计
C程序的结构
C语句:
控制语句
if()~else~;switch();{case…};while()~;do~while();for()~;continue;break;return;goto
函数调用语句
例如:
printf();
表达式语句
例如:
a=10;b=a+10;
空语句
只有一个“;”,用于扩展或者特殊需要
复合语句
把若干语句用{}括起来就是复合语句
C程序的三种基本结构
顺序结构
分支结构
循环结构
基本语句
赋值语句
变量=表达式;
左边必须是变量,右边可以如下:
变量1=变量2=。
。
。
=表达式
不可以:
inta=b=c=2;只能inta=2,b=2,c=2;
复合语句
用{}括起来,只能看成一条语句,而不是多条语句,
从{开始执行,必须执行到}为止
数据输出
输出字符:
putchar()输出一个字符
例如:
putchar(‘a’);putchar(‘\n’)
包含在头文件stdio.h中
格式化输出及输出格式控制符
printf()函数:
(特例,不需包含stdio.h头文件)
printf(“格式控制字符串”,输出表列);
其中格式控制字符串是用双引号引起来的字符串,用于指定输出格式,包括格
式说明和普通字符两种信息构成。
格式说明是以%开头后跟一个格式字符组成
普通字符按原样输出。
输出表列是需要输出的变量或者表达式。
注意:
格式符
%d%o%u%x%c用于处理整形和字符型数据
%s用于处理字符串
%f%e%g用于处理实型数据
允许没有输出表列,即只输出普通字符,但是格式符一定要正确
要输出%要使用%%
%与格式符之间可以指定输出项的宽度和小数点后数据的位数,格式为:
%m[.n]格式字符。
其中域宽为0开头的数时,则输出前导0.
格式符的应用
d格式符
带符号的十进制整形
%d按整形数据的实际长度输出
%md按总域宽m位输出,m足够大时候左边补空格,否则按实际输出
%ld输出长整形数据吗,也可以使用%mld
o,x,u格式符
分别以八进制、十六进制、十进制无符号数形式输出对应的整形数据
当输出的对象有符号时候,求出其补码,并将符号作为数据一部分输出。
例如:
inta=-1;printf(“%o%u%x”,a,a,a);
16位系统中输出:
17777765535ffff内存中存放形式:
16个1
32位系统中为32个1
c格式符
输出字符,对象可以是字符型也可以是整形
对象为整形时候,先将该整数对256求余数,将余数作为ASCII码值输
出对应的符号
也可使用%mc,m足够大时候左边补空格
例如:
inta=65,b=321;printf(“%c%c”,a,b);
结果为AA
s格式符
输出字符串
%s按实际输出
%ms占m列,若m不够字符串宽度则按实际输出,m大左补空格
%-ms同上,编程右补空格
%m.ns占m列,左补,若n>m则m取n值,只输出字符串左端的n个
%-m.ns同上右补空格
f格式符
%f按7位有效数输出,不管输出的数是否有效都有6位小数
%m.nf总域宽m(含小数点),n为小数位数,m足够大左补
否则实际输出
%-m.nf同上右补
e格式符
以指数形式输出实数
%e系统自动给出宽度,13列,小数8位,其中小数位6位,小数点前一
位非零数,指数部分5位e+000形式显示
%m.ne%-m.nem为总宽,n小数位数默认值为6
g格式符
输出实数,根据数值的宽度自动选取f或者e格式中输出宽度较短的,
且不输出无意义的0
数据输入
字符数据的输入
函数名
输入方式
函数原型
getchar()
有回显,需按回车
stdio.h
getche()
有回显,不需回车
conio.h
getch()
无回显,不需回车
conio.h
scanf()的使用
scanf(“格式控制字符串”,地址列表);
地址:
&变量名字
两个格式说明之间无其他符号时候,输入数据时以空格、回车或TAB来分隔数据
若在格式符之间有其他字符,必须原样输入
格式也可以控制宽度,按自左而右截取,但是不能规定小数位数
scanf()没有%u格式,整数一般用d实数用f
选择结构程序设计
if-else语句
if-else语句用于条件判定,其语法如下所示:
if{表达式}
语句1
else
语句2
其中else部分是可选的。
该语句执行时,先计算表达式的值,如果其值为真(即表达式的值为非0),则执行语句1;如果其值为假(即表达式的值为0),并且该语句包含else部分,则执行语句2。
建议在有if语句嵌套的情况下使用花括号。
在C语言中我们会经常用到下列结构:
if(表达式)
语句
elseif(表达式)
语句
elseif(表达式)
语句
elseif(表达式)
语句
else
语句
这种if语句序列是编写多路判定最常用的方法。
其中的各表达式将被依次求值,一旦某个表达式结果为真,则执行与之相关的语句,并终止整个语句序列的执行。
同样,其中各语句既可以是单条语句,也可以是用花括号括住的复合语句。
switch结构
switch(表达式)
{
case常量表达式:
语句序列
case常量表达式:
语句序列
default:
语句序列
}
每一个分支都由一个或多个整数值常量或常量表达式标记。
如果某个分支与表达式的值匹配,则从该分支开始执行。
各分支表达式必须互不相同。
如果没有哪一分支能匹配表达式,则执行标记为default的分支。
default分支是可选的。
如果没有default分支也没有其它分支与表达式的值匹配,则该switch语句不执行任何动作。
各分支及default分支的排列次序是任意的。
注意:
在switch语句中,case的作用只是一个标号,因此,某个分支中的代码执行完后,程序将进入下一分支继续执行,除非在程序中显式地跳转。
跳出switch语句最常用的方法是使用break语句与return语句。
循环结构程序设计
while循环和for循环
while(表达式)
{语句}
在while循环语句中,首先求表达式的值。
如果其值非0,则执行语句,并再次求该表达式的值。
这一循环过程一直进行下去,直到该表达式的值为0为止,随后继续执行语句后面的部分。
for(表达式1;表达式2;表达式3)
{语句}
它等价于下列while语句:
表达式1;
while(表达式2){
语句
表达式3;
}
与表达式3是赋值表达式或函数调用,表达式2是关系表达式。
这3个组成部分中的任何部分都可以省略,但分号必须保留。
如果在for语句中省略表达式1与表达式3,它就退化成了while循环语句。
如果省略测试条件,即表达式2,则认为其值永远是真值,因此,下列for循环语句:
for(;;){...}
是一个"无限"循环语句,这种语句需要借助其它手段(如break语句或return语句)才能终止执行。
do-while循环
do-while循环的语法形式如下:
do
语句
while(表达式);
在这一结构中,先执行循环体中的语句部分,然后再求表达式的值。
如果表达式的值为真,则再次执行语句,依此类推。
当表达式的值变为假,则循环终止。
break语旬与continue语旬
break语句可用于从for、while与do-while等循环中提前退出,就如同从switch语句中提前退出二样。
break语句能使程序从switch语句或最内层循环中立即跳出。
continue语句用于使for、while和do-while语句开始下一次循环的执行。
在while与do-while语句中,continue语句的执行意味着立即执行测试部分;在for循环中,则意味着使控制转移到递增循环变量部分。
continue语句只用于循环语句,不用于switch语句。
某个循环包含的switch语句中的continue语句,将导致进入下一次循环。
goto语句
C语言提供了可随意滥用的goto语句以及标记跳转位置的标号。
最常见的用法是终止程序在某些深度嵌套的结构中的处理过程,例如一次跳出两层或多层循环。
这种情况下使用break语句是不能达到目的的,它只能从最内层循环退出到上一级的循环。
下面是使用goto语句的一个例子:
for(...)
for(...)
{
...
if(disaster)
gotoerror;
}
error:
/*cleanupthemess*/
标号的命名同变量命名的形式相同,标号的后面要紧跟一个冒号。
标号可以位于对应的goto语句所在函数的任何语句的前面。
标号的作用域是整个函数。
数组
一维数组
一维数组的定义
类型说明符数组名[常量表达式];
说明:
常量表达式是数组长度,不能用变量表示,可用符号常数或常量表达式;数组名与变量名不能重复;允许一个类型下说明多个变量和数组;数组名是数组的首地址,即a=&a[0]。
一位数组的初始化
类型说明符数组名[常量表达式]={值,值,……,值};
说明:
可以只给部分元素赋值;只能对元素逐个赋值,不能对数组整体赋值;对全部元素赋值时,可以不定义数组长度,系统自动根据初值个数来决定数组长度;未赋值时候元素值随机。
数组元素的引用
数组名[下标表达式]
说明:
下标表达式可为常量、表达式、变量,取值范围0~元素个数-1,不能越界;只能对数组的元素进行操作。
二维数组
二维数组的定义
类型说明符数组名[常量表达式1][常量表达式2];
例如intb[3][3];在内存中顺序为b[0][0]b[0][1]b[0][2]b[1][0]b[1][1]b[1][2]b[2][0]b[2][1]b[2][2]
说明:
元素按行排列;二维数据可以看做一维数组的数组。
二维数组的初始化
inta[2][3]={{1,2,3},{7,8,9}}或inta[2][3]={1,2,3,7,8,9}
inta[][3]={{1,2,3},{7,8,9}}或inta[][3]={1,2,3,7,8,9}自动计算行数,但是列数不可以省略。
inta[2][3]={{1,2},{5}}相当于inta[2][3]={{1,2,0},{5,0,0}}自动将少的值赋为0.
二维数组的引用
数组名[下标1][下标2];
说明:
俩下标必须放在俩括号内;下标可以是表达式、常量、变量,不能越界。
字符数组
定义、初始化、引用
定义charc[10];、charc[5][10];
初始化
charstr[]={‘c’,’h’,’i’,’n’,’a’}或charstr[5]={‘c’,’h’,’i’,’n’,’a’}以字符常量的形式初始化
charstr[10]={‘c’,’h’,’i’,’n’,’a’}
charstr[]={“china”}以字符串形式初始化,相当于charstr[6]={“china”}
字符串和字符串结束标志
C中没有字符串变量,所以处理字符串常常用字符数组来实现,字符数组相当于字符串变量。
对字符串常量,系统会自动在末尾加\0作为结束标志。
对字符数组,有时候加\0,有时候不加\0,见上初始化。
字符数组的输入输出
逐个
for(i=0;i<20;i++){scanf("%c",&str[i]);}
for(i=0;i<20;i++){printf(“%c”,str[i]);}
说明:
若输入的字符数小于循环数,按回车后会继续等待输入,回车、空格均算字符;若输入字符数大于循环数,则取前面的;输入为缓冲读,接受到回车,scanf才读数据。
整个
scanf(“%s”,&str);
printf(“%s”,str);
说明:
输入时候不能含空格,否则会认为该字符串已经输入完成;自动加结束标志。
常用字符串处理函数
stdio.h
gets(str)从键盘输入字符串存入str数组,可含空格,回车结束
puts(str)将str中字符输出到显示器,直到\0,会将\0转换为\n输出。
string.h
strlen(str)求字符串长度,不包括\0,返回长度值
strcat(str1,str2)将str2字符串连到str1后面,从str1的\0处开始。
strcpy(str1,str2)str2复制到str1中
strcmp(str1,str2)比较俩字符串。
相等返回0,1大返回正数,2大返回负数(绝对值都是ASCII码差值)。
比较规则:
按字符的ASCII码值大小,知道出现第一个不同的字符,即由第一个不同字符的大小决定所在串的大小。
函数
函数概述
模块化程序设计
分而治之;
函数本质:
独立完成任务,可以调用其它函数,内部工作对外不可见。
main函数开始,main函数结束,main函数可以调用其它函数,不可被调用。
函数的分类
库函数、用户定义函数;
有返回值函数(必须定义返回值类型)、无返回值函数(void);
无参函数、有参函数。
函数的定义及调用
函数定义
无参函数:
类型标识符函数名()
{
声明部分
语句
}
有参函数:
类型标识符函数名(类型名形参1,类型名形参2,……)
{
声明部分
语句
}
空函数
函数名(){}用于扩充功能预留。
说明:
函数不能嵌套定义;形参必须分别定义类型。
函数参数传递
实参是函数调用时候括号里的参数,参数传递是单向的,由实参到形参;
只有被调用时,函数的形参才会分配内存空间,函数完成后释放内存空间;
形参的值变化不会影响到实参;
实参形参的顺序、数量、类型必须一致;
实参可以使变量、常量、表达式,但必须有确定值;
形参说明两种方式:
intmax(x,y)
intx,y;
intmax(intx,inty)
函数的返回值
通过return函数返回值:
return表达式;或者return()表达式;
return函数终止函数的执行,返回表达式的值,每个函数只能执行一个return语句;
无return语句的函数返回值不确定;
返回值应该和函数的定义类型一致,若不一致,强制转换为函数类型。
无返回值定义为void,默认是int型。
函数调用和参数传递
函数的调用
函数名(实参列表);或者函数名();
调用方式:
printf(”……”);作为独立语句
r=max(a,b)+min(c,d);作为表达式
x=max(max(a,b),min(c,d));作为函数的参数
函数声明与函数原型
函数必须存在才能被调用,库函数要包含相应的头文件;
函数在调用之前要声明,声明格式:
类型标识符函数名(类型名形参1,类型名形参2,……);
形参名字无所谓;
声明只是告诉编译系统该函数的一些信息,以便进行语法检查,注意区分与函数定义的区别。
下列情况不需声明即可调用:
函数定义出现在主调用函数之前;如果在所有函数定义之前、文件的开始、函数的外部已经预先声明了,那不需再声明;库函数不需声明,包含相应的头文件即可。
函数的嵌套调用
不允许嵌套定义,允许嵌套调用,即函数定义中又调用了别的函数。
数组作为函数参数
数组元素作函数实参
数组元素作为实参,可以看做是普通变量,不要求形参也是下标变量,而且传递的是值,遵循参数单向传递。
数组名作为函数参数
数组名可以做形参、实参;系统不为形参数组分配地址,实参向形参只是传送地址,这样被调函数可以实现对主调函数数组的操作。
例如:
floataver(floata[])
{
函数体
}
voidmain()
{
floatscore[10],av;
av=aver(score);
}
说明:
形参数组和实参数组类型必须一致;长度可不同,形参长度可不定义,只传递首个地址。
函数的递归调用
函数的递归调用是指一个函数在它的函数体内,直接或间接地调用它自身。
直接递归调用:
在调用hs函数过程,又调用hs函数;
间接递归调用:
在调用hs1函数的过程中,调用了hs2函数,而在调用hs2函数的过程中又调用了hs1函数。
防止无终止运行,必须有终止递归的条件。
递归调用两个阶段:
递推阶段:
将原问题分解为新的子问题,最终达到已知的条件
回归阶段:
从已知条件出发,逐一求值回归,最终达到递推的开始处,完成递归调用。
变量的作用域及其存储类型
局部变量
局部变量是指在程序块或者函数内定义的变量(内部变量),只能被定义它的程序块或者函数访问,函数或程序块结束执行时,系统收回其内存空间。
C中的局部变量:
函数体内定义的变量(包括main函数);复合语句中定义的变量;形参。
说明:
访问变量有同名时,采用局部有限的原则;不同函数的局部变量名字可相同。
全局变量
在函数外部定义的变量;也称外部变量。
作用域:
从定义开始到文件结束。
优点:
增加函数间数据联系的渠道,从函数得到一个以上的返回值,减少函数实参与形参耳朵个数,减少内存空间以及传递数据时的时间消耗。
缺点:
不符合模块化程序设计的原则(函数是一个封闭的整体),使得函数的移植性、通用性、可读性降低;各个函数都可能改变全局变量的值,容易出错;长时间占用存储单元。
外部变量的声明:
在外部变量的定义之前如果需要引用,那就需要声明externa;
声明只是说明有这个外部变量,只有定义外部变量时候才分配内存单元;声明可以出现多次,定义只能出现一次。
外部变量与局部变量同名时候,局部变量会屏蔽全局变量(局部优