c语言基础
2020-09-18 23:38:19 0 举报
AI智能生成
c语言基础
作者其他创作
大纲/内容
1.c语言简介和历史
计算机和编程语言
什么是计算机语言
程序是用特殊的编程语言写出来表达如何解决问题的
不是用编程语言来和计算机交谈,而是描述要求它如何做事情的过程或方法
算法
定义
计算的步骤
程序的执行
解释
借助一个程序,那个程序能试图理解你的程序然后按照你的要求执行
编译
将程序翻译成计算机能懂的语言(机器语言),然后程序就能直接执行了
解释语言vs编译语言
1.语言本身无法编译/解释之分
2.常用的执行方式而已
3.解释型语言有特殊的计算能力
例如:可以在运行中进行修改
4.编译型语言有确定的运算性能
c语言
c语言的历史与发展
c语言是从B语言发展而来<br>
<br>Bcpl是从FORTRAN发展而来
B语言精炼,接近硬件,但过于简单,无数据类型
最初的c语言只是位描述和实现UNIX操作系统提供一种工作语言而设计
语言支持指针间接方式
c语言受到PL/l的影响,还和PDP-ll的机器用语言有很大的关系
1973年11月,第四版的Unix发布,全是由c语言编写、
c语言与版本-标准
经典c
又被称为“K&R the C”, 1978 年,Dennis Ritchie 和 Brian Kernighan 合作推出了《The C Programming Language》的第一版(按照惯例,经典著作一定有简称,该著作简称为 K&R),书末的参考指南 (Reference Manual) 一节给出了当时 C 语言的完整定义,成为那时 C 语言事实上的标准,人们称之为 K&R C。从这一年以后,C 语言被移植到了各种机型上,并受到了广泛的支持,使 C 语言在当时的软件开发中几乎一统天下。
'83或ANSIC
1983年,美国国家标准协会(ANSI)成立委员会,定制第一个c语言标准草案
c89(ANSI)
1989年ANSI发布c89,在1990年国际标准化组织ISO(International Organization for Standardization,ISO)接受了ANSI的标准
c90(ISO)
随后,《The C Programming Language》第二版开始出版发行,书中内容根据 ANSI C(C89)进行了更新。1990 年,在 ISO/IEC JTC1/SC22/WG14 (ISO/IEC 联合技术第 I 委员会第 22 分委员会第 14 工作组) 的努力下,ISO 批准了 ANSI C 成为国际标准。于是 ISO C(又称为 C90) 诞生了。除了标准文档在印刷编排上的某些细节不同外,ISO C(C90) 和 ANSI C(C89) 在技术上完全一样。
c95
ISO 在 1994、1996 年 分别出版了 C90 的技术勘误文档,更正了一些印刷错误,并在1995 年通过了一份 C90 的技术补充,对 C90 进行了微小的扩充,经过扩充后的 ISO C 被称为 C95
c99
<ul><li>2001、2004年先后进行了两次技术修正(TC1和TC2)。 ISO/IEC 9899:1999(及其技术修正)被称为 C99<br></li><li>C99是C89(及1995基准增补1)的扩充。本书的叙述以C99标准为依据。本书中程序基本上都可以在目前所用的编译系统(如VC++ 6.0,Turbo C++ 3.0,GCC)上编译和运行<br></li></ul>
c语言用在哪里
操作系统
嵌入式系统
驱动系统
底层驱动
图形引擎,图像处理,声音效果
编译 -> 运行
c语言需要编译才能运行(需要下面中的一个)<br><ul><li>编译器<br></li><li>编辑器<br></li><li>IDE(集成开发环境)<br></li></ul>
<ul><li>上机输入与编辑源程序<br></li><li>对源程序进行编译<br></li><li>与库函数连接<br></li><li>运行目标程序<br></li></ul>
c语言主要特点
语言表达能力强
具有数据类型构造能力和结构化的程序控制结构
语言简洁,紧凑使用方便灵活
能使编译程序产生执行效率较高的代码
可编写移植性较好的程序
结构化程序设计方法
采用自顶向下,逐步求精的程序设计方法
使用三种基本控制结构造程序
结构化程序设计的主要设计语言
原则:自顶向下,逐步细化,模块化设计
2.简单的程序
iinclude<stdio,h><br>#include<stdlib.h><br>int main(void)<br>{<br> //输出一句话<br> print(“hello”);<br>}
注释
功能:让别人能看懂代码
符号
//
单行注释
/**/
多行注释(块注释)
注意:注释的结尾不确定
主函数
应用程序入口,操作系统调用程序的接口
注意:一个项目只有一个主函数
单个文件只能出现一个
多个文件只能一个 文件夹一个
常见的五种格数
int main(void)<br>{<br> return 0;<br>}
c语言标准主函数模式(c99)
void表示不接受任何函数
无void表示参数类型和数量不确定
int main(int argc,char* argv[])<br>{<br> return 0;<br>}
c/c++标准主函数形式,使用命令参数
int main()<br>{<br> return 0;<br>}
c++标准主函数形式
main()<br>{}
老标准(c89)支持的写法,现在也可以写。但尽量不要写
void main()<br>{ }
这种主函数写法逻辑上复合,而且很多系统支持,但是考虑到代码的移植性,建议用标准的形式进行书写。
return 0;
0表示正常结束
逻辑的连贯性
标准规定
头文件
#include<stdio.h>
标注输入输出头文件
就是让函数是可用的
<b>输入输出<br></b>后面会有详细解释
printf
内置函数
常用的函数,是编译器中定义好的
增加程序的效率
不是所有的编译器都有,还是加上头文件好
算法
变量和常量
变量
定义
其值可以改变的量称为变量
变量的三要素
<b>变量名</b>:每个变量都应该有一个名字
<b>变量的数据类型</b>:每个变量都应该具有一个数据类型(在定义是指定)内存中占据一定的存储空间
<b>变量的值</b>:变量对应的存储空间中存放的数
使用变量的基本规则
变量必须先定义,后使用
所有变量必须在第一条可执行语句前定义
定义一个变量
变量格式:数据类型 变量名称;<br> 数据类型 变量名称 = 值;<br>--<br>一条申明语句可以声明若干同类型的变量
变量初始化
定义
在定义一个变量的时候要赋值
格式
单个变量:类型名称 变量名称 = 初始值;<br>
int price= 0;
组合变量:<br>
int price = 0 ,amoum = 100;
变量的赋值
定义
将某一数值赋给某个变量的过程,称为赋值
例如
int a = 1;
其中“=”是赋值运算符
变量的输入输出
输入
scanf函数进行输入
格式
scanf("%数据类型",&变量名);
标识符
定义
标识符就是程序员自己规定的具有特定含义的词,比如类名称,属性名称,变量名等
标识符的命名规则
标识符由字母(A-Z,a-z)、数字(0-9)、下划线“_”组成,并且首字符不能是数字,<br>但可以是字母或者下划线
不能把C语言关键字作为用户标识符
标识符对大小写敏感,即严格区分大小写。一般对变量名用小写,符号常量命名用大写
标识符命名应做到“见名知意”,例如,长度(length),求和、总计(sum),圆周率(pi)……
常量
定义
值不能被改变的量称为常量
例如
int const *p; /* 定义的就是常量 */<br>int * const p; /* 定义的还是常量 */
const是一个修饰符,const的属性表示这个变量值一旦初始化就不能在修改
int a = 1;
1就是一个常量
宏常量(符号常量)
一般采用大写字母表示
格式
#define 标识符 字符串
例如 <br>#include <stdio.h><br><b><font color="#f384ae">#define PRICE 30 </font></b><br>void main( )<br>{<br> int num,total;<br> num=101;<br> total=num*PRICE;<br> printf("total=%d\n",total);<br> return;<br> } <br>
运算符和表达式
运算符
算术运算符
<b>定义</b>:用来进行变量计算的符号
+
<b>加法运算符</b>,或正值运算符。如3+5、+3
-
<b>减法运算符</b>,或负值运算符。如5-2、-3
<br>%
<b>模运算符</b>,或称<b>求余运算符</b>,%两侧均应为整型数据,如7%4的值为3)。只能对整型或字符型数据进行运算。
/
(<b>除法运算符</b>,如5/3)。两个整数相除结果为整数,如5/3的结果为1,舍去小数部分。同样的1/2=0。
*
<b>乘法运算符</b>,如3*5
++
<b>自增运算符 </b>
只能用于变量,不能用于常量或表达式 。<font color="#c41230"><b>结合方向</b></font>(自右向左)
前置自增
在使用i之前,先使i的值<b><font color="#c41230">加1</font></b>
例如:<br> j=++i; (i的值加1,再赋给j<br>
后置自增
在使用i之后,使i的值<b><font color="#c41230">加1</font></b>
例: <br> j=i++; (先将i的赋给j,然后i在加1) <br>
--
<b>自减运算符</b>
前置自减
在使用i之前,先使i的<b><font color="#c41230">减1</font></b>
例如:<br> j=--i; (i的值加1,再赋给j)
后置自减
在使用i之后,使i的值<b><font color="#c41230">减1</font></b>
例: <br>j=i++; (先将i的值赋给j,,然后i减1)
常用的标准数学函数
关系运算符
>
大于
<
小于
==
等于
>=
大于等于
<=
小于等于
!=
不等于
逻辑运算符
!
逻辑非(相当于其他语言中的NOT) <br>
&&
逻辑与(相当于其他语言中的AND) <br>
| |
逻辑或(相当于其他语言中的OR) <br>
位运算符
定义: 位运算是指进行二进制位的运算
用处
在系统软件中,常要处理二进制位的问题
例如<br>将一个存储单元中的各二进位左移或右移一位,两个数按位相加等
>>
右移
a>>2 表示<font color="#c41230">将a的各二进位右移</font>2位。移到<font color="#c41230">右端的低位被舍弃</font>,对无符号数,<font color="#c41230">高位补0</font>
如a=017时:<br> a为 00001111, a>>2为 00000011 11(此二位舍弃)<br> 右移一位相当于除以2,右移n位相当于除以2n 。 <br>
<<
左移
用来将一个数的<font color="#c41230">各二进位全部左移若干位</font>
例如:<br> a=a<<2<br> 将a的二进制数左移2位,右补0。若a=15,即二进制数00001111,<br>左移2位得00111100,即十进制数60
~
取反
~是一个单目(元)运算符,用来对一个<font color="#c41230">二进制数按位取反</font>,<font color="#c41230">即将0变1,1变0</font>。<br> 例如~025是对八进制数25(即二进数00010101)按位求反。 <br>
例如~025是对八进制数25(即二进数00010101)按位求反。 <br> a= 0000000000010101<br> ~a= 11111111111101010 <br>
|
按位或
参加运算的两数据,按二进位进行“或”运算。如果两个相应的<font color="#c41230">二进位</font>中<font color="#c41230">只要<br>有一个为1</font>,该位的<font color="#c41230">结果值为1</font>。即0|0=0;0|1=1;1|0=1;1|1=1。 <br>
例如:060|017 <br> 00110000<br><u> (|) 00001111 <br></u> 00111111 <br>
^
按位异或
异或运算符也称<b>XOR运算符</b>。它的规则是若参加运算的<font color="#c41230">两个二进位相同</font>,则<font color="#c41230">结<br>果为0(假);不同则为1(真)</font>。即0^0=0;0^1=1;1^0=1;1^1=0;<br>
00111001 (十进制数57,八进制数071)<br><u> (^) 00101010 </u> (十进制数42,八进制数052)<br> 00010011 (十进制数19,八进制数023) <br>
&
按位与
参加运算的两数据,按二进位进行“与”运算。如果两个相应的<font color="#c41230">二进位都为1</font>,<br>则该位的<font color="#c41230">结果值为1</font>,否则为0。即0&0=0;0&1=0;1&0=0;1&1=1; <br>
例如:3&5=?。<br> 3=00000011<br><u> (&) 5=00000101</u><br> 00000001
注意点
位运算符中除“~”以外,均为双目(元)运算符。 <br>
运算量只能是整型或字符型的数据,不能为实型数据
<b><font color="#381e11">不同长度的数据进行位运算</font></b><br> 如果两个数据长度不同(<font color="#381e11">例如long型和short型</font>)进行位运算时(如a&b,而a为long型,b为short型),系统会将<font color="#c41230">二者按右端对齐</font>。<font color="#c41230">如果b为正数,则左侧16位补满0。若b为负数,左端应补满1。如果b为无符号整数型,则左侧添满0</font>
例题
【例3.6】 将一个short整数a对应的二进制位从右端开始的4~7位二进制取出来组成另一个数。<br>#include <stdio.h><br>void main()<br>{<br> unsigned a,b,c,d;<br> scanf("%o",&a);<br> b=a>>4;<br> c=~(~0<<4);<br> d=b&c;<br> printf("%o,%d\n%o,%d\n",a,a,d,d);<br>return;<br>} <br>
子主题
赋值运算符
<b>定义</b>:赋值符号“=”就是赋值运算符,它的作用是将一个数据赋给一个变量
= 即其扩展运算符
=
就是进行赋值
复合的赋值运算符
算术运算符和赋值运算符
在应用中经常碰到“a=a+3”等情况,在C中允许将它变为“逆波兰”式情况,即“a+=3”,以提高运行效率
+=
-=
*=
/=
%=
位运算符和赋值运算符
位运算符与赋值运算符可以组成复合赋值运算符<br>--<br>例如,a&=b相当于a=a&b。a<<=2相当于:a=a<<2<br>
&=
|=
<<=
>>=
^=
条件运算符
?:
<b><font color="#000000">表达式为:</font></b>表达式1?表达式2:表达式3
<br>例如:<br>1、max=(a>b)?a:b<br>就是将a和b二者中较大的一个赋给max。<br>2、min=(a<b)?a:b<br>就是将a和b二者中较小的一个赋给min。<br>
逗号运算符
,
指针运算符
*和&
求字节运算符
sizeof()
求不同的数据类型占的字节数
强制类型转换运算符
(数据类型)
强制数据类型转换
含义:可以利用强制类型转换运算将一个表达式转换成所需类型。
一般形式
(类型名)(表达式) <br>
例如:<br>(double)a //将a转换成double型<br>(int)(x+y) //将x+y的值转换成整型 <br>
注意
需要说明的是在<font color="#c41230">强制类型转换</font>时,<font color="#c41230">得到</font>一个所需类型的<font color="#c41230">中间变量</font>,<font color="#c41230">原来变量</font>的<font color="#c41230">类型未发生变化</font>
例题
#include <stdio.h><br>void main( ) <br>{ <br>float x;<br>int i;<br>x=3.6;<br>i=(int)x; //进行类型的强制转换<br>printf("x=%f,i=%d\n",x,i);<br>} <br>
成员运算符
. →
通过符号指定结构或者联合中的某个成员,进行操做
下标运算法
[]
表达式
简介:表达式是用<font color="#f384ae">运算符</font>号将,<font color="#f384ae">常量</font>,<font color="#f384ae">变量</font>,<font color="#f384ae">函数</font>等<font color="#f384ae">连接</font>成有意义的式子<br> 表达式是<font color="#f384ae">操作数和运算符的结合体</font>,它产生一个单一的值,<font color="#f384ae">操作数</font>在表达式中是<font color="#f384ae">被运算的对象</font>
赋值表达式
<b>定义</b>:由赋值运算符将一个变量和一个表达式连接起来的式子称为赋值表达式。
一般形式为<br>
〈变量〉 〈赋值运算符〉 〈表达式〉。 <br>
运算过程
对赋值表达式求解的过程是:将赋值运算符右侧的“表达式”的值赋给左侧的变量。 <br>
例如
a=b=c=5 //赋值表达式值为5,a、b、c值均为5<br>
a=5+(c=6) //表达式值为11,a的值为11,c的值为6<br>
a=(b=4)+(c=6) //表达式值为10,a的值为10,b等于4,c等于6 <br>
逗号表达式
一般形式为
表达式1,表达式2,表达式3,……,表达式n <br>
例如
x=(a=3,6*3) //第1个表达式<br>x=a=3,6*a //第2个表达式<br>-<br> 第1个是赋值表达式,将一个逗号表达式的值赋给x,x的值等于18。<br>第2个是逗号表达式,它包括一个赋值表达式和一个算术表达式,x的值为3。 <br>
printf("%d,%d,%d",a,b,c);<br> 上一行中的“a,b,c”并不是一个逗号表达式,它是printf函数的3个参数,参数间用逗号间隔。<br>-<br>如果改写为:<br> printf("%d,%d,%d",(a,b,c),b,c);<br>则“(a,b,c)”是一个逗号表达式,它的值等于c的值<br>
例题
#include <stdio.h><br>void main( ) <br>{ <br>int a,b,c;<br>c=(a=2,b=5,a++,++b,a+b);<br>printf("c=%d\n",c);<br>return;<br>} <br>--<br>解题思路:<br>括号中<br>1.先给a和b都进行赋值<br>2.a++ 等于3<br>3.++b 等于6 这里不用考虑前置和后置,因为不是赋值和输出<br>4.a+b 等于9
关系表达式
介绍
用关系运算符将两个表达式(可以是算术表达式、关系表达式、逻辑表达式、赋值表达式、字符表达式)连接起来的式子
内容
关系表达式运算出的结果为0和非0
o表示假,即该关系不成立
非0,表示真,即该关系成立
逻辑表达式
介绍
用<b>逻辑运算符</b>将<b>关系表达式</b>或<b>逻辑量</b>连接起来的<b>有意义</b>的式子
简介
<font color="#c41230" style=""><b>逻辑表达式的值</b>应该是一个<b>逻辑量</b></font>“真”或“假”。C语言编译系统以数值<font color="#c41230">1代表“真”,<br>以0代表“假”</font>,但在判断一个量是否为“真”时,以0代表“假”,以非0代表“真”
<b><font color="#c41230">逻辑运算符两侧的运算对象</font></b>不但可以是<font color="#c41230">0和1</font>,<font color="#c41230">或者是0和非0的整数</font>,也可以是<font color="#c41230">任何类型的数<br>据。可以是字符型,实型或指针型等</font>。系统最终以0和非0来判定它们属于“真”或“假”。
例如:<br>5>3&&2||8<4-!0 <br>
在逻辑表达式的求解中,并<b><font color="#c41230">不是所有的</font></b><font color="#c41230">逻辑运算符<b>都被执行</b></font>,只是在<b><font color="#c41230">必须</font></b><font color="#c41230">执行下一个</font>逻辑运算<br>符才能求出表达式的解时,才执行该运算符
例如
① a&&b&&c 只有<b><font color="#c41230">a为真</font></b>(非0)时,<b style="color: rgb(196, 18, 48);">才</b><font color="#8a8a8a">需要</font><b style="color: rgb(196, 18, 48);">判别b的值</b>,只有<font color="#c41230">a和b都为真</font>的情况下<font color="#c41230">才需要判<br>别c的值</font>。<font color="#c41230">只要a为假,就不必判别b和c</font>(此时整个表达式已确定为假)。如果<font color="#c41230">a为真,b为假,<br>则不判别c</font>,整个表达式运算结果。<br>② a||b||c 只要a为真(非0),就不必判断b和c;只有a为假,才判别b;a和b都为假才判别c。
例题
【例3.5】逻辑运算符的应用。<br>#include <stdio.h><br>void main( ) <br>{ <br>int x=4,y=5,z,m;<br>z=(x++==5) && (++y);<br>printf("z=%d,x=%d,y=%d\n",z,x,y);<br>m=(x++) || (++y);<br>printf("m=%d,x=%d,y=%d\n",m,x,y);<br>return;<br>} <br>
条件表达式
含义:条件表达式由条件运算符构成,并常用条件表达式构成一个赋值语句。
一般形式
x=<表达式1>?<表达式2>:<表达式3><br>其意义是:<br>先求解表达式1,若为非0(真),则求解表达式2,将表达式2的值赋给x。<br>若为0(假),则求解表达式3,将表达式3的值赋给x。 口诀:前真后假。<br>
例如:<br>min=(a<b)?a:b;<br>相当于:<br>if(a<b)<br> min = a;<br>else<br> min =b;<br>效果是将a、b中较小的那个赋给min。
多个表达式
x=<表达式1>?<表达式2>:<表达式3>?<表达式4>:<表达式5>···<br>执行顺序是从右到左依次判断再求出最后的x,即所谓的右结合性。<br>
例如: <br>a>b?a:c>d?c:d <br>应理解为 <br>a>b?a:(c>d?c:d)<br><br>这也就是条件表达式嵌套的情形,即其中的表达式3又是一个条件表达式.
注意:此表达式后边无需加 “;”。
优先级
在表达式求值时,先按运算符的优先级别高低次序执行
优先次序(常见的)
算术运算符>关系运算符>赋值运算符<br>-<br>关系运算符前(<,<=,>,>=)的优先级别相同,(!=,==)优先级相同,前4种高于后2种。
逻辑运算符<br>(1) !(非)→算术运算符→关系运算符→&&(与)→||(或)。<br>
例如:<br>(a>b)&&(x>y) //可写成a>b&&x>y<br>(a= =b)||(x= =y) //可写成 a= =b||x= =y<br>(!a)||(a>b) //可写成!a||a>b <br>
所有的优先级
子主题
子主题
结合型
算术运算符的结合方向为“自左至右的结合方向”又称“左结合性”,即运算对象先与左面的运算符结合。例如:-a+b <br>
输入和输出
C语言本身<font color="#f384ae">不提供输入输出语句</font>,输入输出的操作是<font color="#f384ae">C标准函数库中提供了输入和输出函数</font>
输出
定义:是以计算机主机位主体而言的。从计算计向输出设备(如显示器,打印机等)输出数据称为<font color="#f384ae">输出</font>
输入
定义:从输入设备(如键盘,磁盘,光盘等)向计算机输入数据称为<font color="#f384ae">输入</font>
标准输入输出函数
putchar(输出字符),getchar(输入字符),<b><font color="#f384ae">printf(格式输出),scanf(格式输入</font></b>),puts(输出字符串),gets(输入字符串)
printf函数
一般格式
printf(“格式控制”,输出表列);
例如:printf("数字是 %d",a);
<b>“格式控制”</b>:是用双撇号括起来的一个字符串,称为”<b><font color="#f384ae">转换控制字符串</font></b>“,简称<b><font color="#f384ae">”格式字符串“</font></b>它包括两个信息
格式声明
作用:是将输出的诗句转换为指定的格式然后输出。
格式:格式声明式由%号开头的 如%d,%f等
普通字符
作用:需要字符即需要在输出时<font color="#f384ae">原样输出</font>的字符。 例如双撇号中的汉字逗号空格等
<b>输出表列</b>:是程序需要输出的一些数据,可以是常量,变量或表达式
格式符
作用:对应不同的类型的数据要使用不同的格式声明
数据输出的格式符
d 格式符
用来输出一个十进制的整数
输出整形是%d
输出长整形是%ld
输出双长整形是%lld
特殊使用
指定输出数据的宽度,而这种格式是指定输出数据的<font color="#f384ae"><b>宽域</b></font>
printf("%5d",5);
输出数据占5列,而输出的数据显示在第5列的右侧
f 格式符
用来输出实数(包括单,双精度,长双精度)以小数形式输出
特殊使用
指定数据宽度和小数位数用%m.nf
printf("%5.2f",5.555);
输出的数据占5列,其中包括两个小数
字符输出的格式符
c 格式符
用来输出一个字符
特殊使用
字符输出也可以使用<b><font color="#f384ae">宽域</font> </b>
一个整数也可按字符型输出。在输出这个整数前,系统会将其转换成ASCII码<br>--<br>当数字超过ASCII码的范围是就会减去255在循环查找一遍
例如:<br>short a = 123;<br>printf("%c",a);
例如:<br>short a =555;<br>prinf("%c",a);
s 格式符
用来输出一个字符串
C语句的作用和分类
三种基本结构
顺序结构
顺序结构就是按照顺序自上向下运行
选择结构
含义
选择结构用于判断给定的条件,根据判断的结果判断某些条件,根据判断的结果来控制程序的流程。
选择语句
if语句
关键词
if
else
if语句是可以嵌套使用的
一般形式
if(表达式)<br> 语句1;
if(表示式)<br> 语句1;<br>else <br> 语句2;
<b><font color="#000000">表达式可以是</font></b>:关系表达式,逻辑表达式,数组表达式
<b><font color="#000000">语句</font></b>:简单的语句,复合语句,另一个if语句等
最常见的3种if语句形式
1. if (表达式) 语句1 (没有else子句)<br>
2. if (表达式) 语句1 <br> else 语句2 (有else子句)<br>
<br>3. if(表达式1) 语句1<br> else if(表达式2) 语句2<br> else if(表达式3) 语句3<br> ┆<br> else if(表达式m) 语句m<br> else 语句m+1<br> (在else部分又嵌套了多层的if语句) <br>
switch语句
含义:是c语言中的开关语句
用法:switch语句的作用是根据表达式的值,使流程转到不同的语句
三个关键词
switch
case
标签的作用,用来标志一个位置
default
标签的作用,用来标志一个位置
一般式
switch语句的一般形式:<br>switch(表达式)<br>{ case 常量1 :语句1;<br> case 常量2 :语句2;<br> ┇ ┇ ┇<br> case 常量n :语句n;<br> default : 语句n+1;<br>} <br>
注意点
表达式是<b style=""><font color="#c41230">整数,和字符型数据</font></b>
语句中的<b><font color="#c41230">常量1到常量n不能相同</font></b>
当<b><font color="#c41230">没查找</font></b>到相同的语句时可以使用<font color="#c41230">default</font>来进行<font color="#c41230">输出提示语句</font>
例如
#include<stdio.h><br>int main()<br>{<br> double score;printf("请输入分数:\n");<br> scanf("%lf",&score);switch((int)(score/10)) //switch((int)score/10)出现严重错误<br> { <br> case 10: <br> case 9:printf("A(最好)\n");break; <br> case 8:printf("B(优秀)\n");break; <br> case 7:printf("C(良好)\n");break; <br> case 6:printf("D(及格)\n");break; <br> case 5:<br> case 4:<br> case 3:<br> case 2:<br> case 1:<br> case 0:printf("E(不及格)\n");break;<br> default:printf("Error!\n");<br> }<br>}
循环结构
while语句
特点:先判断条件表达式,后执行循环体语句
一般形式
while (表达式) //循环条件<br>{<br> 语句 //循环体<br>}
do while语句
特点:先执行循环体,在判断循环条件是否成立
一般形式为
do{<br> 语句 //循环语句<br>} <br> while (表达式);//判断条件 <br>
while和do while的不同点
#include <stdio.h> <br><br>int main( )<br>{<br> int i,sum=0;<br> <br> scanf("%d",&i);<br> printf("i = %d\n",i);<br> <br> while(i<=10) <br> {<br> sum=sum+i;<br> i++;<br> }<br> printf("sum=%d\n",sum);<br> <br> do <br> {<br> sum=sum+i;<br> i++;<br> }while(i<=10);<br> printf("sum=%d\n",sum);<br><br>}
当i<=10为真时
当i<=10为假时
当while后面的表达式的<font color="#c41230">第一次的值为“真”</font>时,两种循环得到的<font color="#c41230">结果相同</font>;<font color="#c41230">否则不相同</font> <br>
for语句
一般形式
for(表达式1;表达式2;表达式3)<br> { <br> 语句<br>} <br>
表达式1:初始条件,只执行一次<br>表达式2:循环条件,用来判定是否继续循环|<br>表达式3:循环变量增值,使循环能结束 <br>
注意点
<b><font color="#000000">部分的表达式可以省略</font></b><br>如:<br>for(;表达式2;表达式3) <br> for(;表达式2;) <br>
<b><font color="#000000">变量的定义可以与循环变量无关</font></b> <br>如:<br>for (sum=0 ; i<=100; i++) <br> sum=sum+i; <br>
<b><font color="#000000">两边的表达式可以是逗号表达式</font></b><br>如<br> for(sum=0,i=1 ; i<=100; i++) <br> sum=sum+i; <br>for(i=0,j=100 ; i<=j; i++,j-- ) <br> k=i+j; <br> <br>
执行步骤
(1) 求解表达式1<br>(2) 求解表达式2,若值为真,执行循环体语句,再转第(3)步。若为假,则结束循环 <br>(3) 求解表达式3<br>(4) 转回第(2)继续执行 <br>
循环的嵌套
一个循环体内又包含另一个完整的循环结构称为循环的嵌套
三种循环可互相嵌套
合法形式
while()<br>{<br> ...<br> while()<br> {<br> ...<br> }<br>}
do<br>{<br>do<br>{...}<br>while();<br>}while();<br>
for(;;)<br>{<br> for(::)<br> {...}<br>}
(4) while( ) (5) for(;;) (6) do<br> {… { … {…<br> do{…} while( ) for(;;)<br> while( ) ; { } { }<br> {…} … }<br> } } while( ); <br>
N-S流程图
子主题
break和continue语句
break
从循环体内跳出,即提前结束循环,接着执行循环下面的语句. <br>
continue
用来结束本次循环,即跳过循环体中下面尚未执行的语句,判定是否执行<br>下一次循环。 <br>
区别
<font color="#c41230"><b>continue</b></font>语句只结束本次循环,而不是终止整个循环的执行。 <br>
<b><font color="#c41230">break</font></b>语句结束整个循环过程,不再判断执行循环的条件是否成立。 <br>
数据类型
基本数据类型
数值类型
整形常量
就是1,2,3,4,5,6
当写个整数,默认就是int类型的数据,或者计算机会以int类型处理它
基本整形int
整数,在目前绝大多数机器上占4个字节。TC2中是2个字节 <br>
短整形short int
一般2个字节长。通常简写为short <br>
长整形long int
一般是4个字节长。通常简写为long <br>
双长整形 long long int
一般是8字节,取值范围-2*63~(-2*63-1),通常简写long long
signed
用来修饰int、short和long,说明他们是有符号的整数(正整数、0和负整数)。一般缺省都是有符号的,所以这个修饰符通常省略
unsigned
用来修饰int、short和long,说明他们是无符号的整数(正整数和0) <br>
浮点型(实型)常量
单精度 float
双精度 double
复数浮点型 float_complex, double_comple, long long_comple
番外
指数形式
介绍
由十进制数,加阶码标志“e”或“E”以及阶码( 只能为整数,可以带符号)组成。
格式
a E n(a为十进制数,n为十进制整数),<br> 其值为a×10n<br> 如:2.1E5(等于2.1×105)。 <br>
隐式类型转换
<b>横向</b>向左的箭头表示必定的转换,如字符数据必定先转换为整数,<br>short型转换为int型,float型数据在转换时一律先转换成双精度型。 <br>
<b>纵向</b>箭头表示运算对象为不同类型时转换的方向。例如int型与double型<br>数据进行运算,先将int型的数据转换成double型, 然后在两个同类型(d<br>ouble型)数据间进行运算,结果为double型。 <br>
将<b><font color="#c41230">实型数据</font></b>(包括单、双精度)赋给<font color="#c41230" style="">整型</font>变量时,<font color="#c41230" style="">舍弃</font>实数的<font color="#c41230" style="">小数部分</font>。<br>-<br>如i为整型变量,执行“i=3.56”的结果是使i的值为3,在内存中以整型形式存储。 <br>
将<b style="color: rgb(196, 18, 48);">整型数据</b><font color="#5c5c5c">赋</font>给<font color="#c41230">单、双精度变量</font>时,<font color="#c41230">数值不变</font>,但以<font color="#c41230">浮点数形式存储到变量中</font><br>-<br>如将23赋给float变量f,即f=23,先将23转换成23.00000,再存储在f中。 <br>
将一个<b><font color="#c41230">double型数据</font></b>赋给<font color="#c41230">float</font>变量时,<font color="#c41230">截取</font>其<font color="#c41230">前面7位</font>有效数字,存放到<font color="#c41230">float变量的存储单元</font>(32位)中。<br>-<br>如:<br> float f;<br> double d=123.456789e100;<br> f=d; // 编译提示:conversion from 'double ' to 'float ', possible loss of data<br> 将一个float型数据赋给double变量时,数据不变,有效位数扩展到16位,在内存中以64位(bit)存储。 <br>
<b><font color="#c41230">字符型数据</font></b>赋给<font color="#c41230">整型变量</font>时,由于字符只占1个字节,而整型变量为4个字节,因此将<font color="#c41230">字符数据(8位</font>)放到<font color="#c41230">整型变量低8位中</font><br>
将一个<b><font color="#c41230">int、short、long型数</font></b>据赋给一个<font color="#c41230">char型变量</font>时,<font color="#c41230">只</font>将其<font color="#c41230">低8位</font>原封不动地送到char型变量<br>--<br>例如:<br>int i=289;<br>char c=’a’;<br>c=i;<br>c的值为33,如果用“% c”输出c,将得到字符“!”(其ASCII码为33)。 <br>
字符型
char
介绍
字符型常量是用单引号括起来的一个字符
特点
(1) 字符常量只能用单引号括起来,不能用双引号或其他括号
(2) 字符常量只能是单个字符,不能是字符串(双引号括起来的内容称为字符串)。 <br>
(3) 字符可以是字符集中任意字符。 <br>
/
定义
转义字符是一种特殊的字符常量
特点
转义字符以反斜线“\”开头,后跟一个或几个字符。转义字符具有特定的含义,<br>不同于字符原有的意义,故称“转义”字符。
转义的图片
布尔型
bool
指针(*)
前述
指针是一个值为内存地址的变量(或数据对象)
指针类型
基本数据类型的指针
char,short,int,long,longlong,float,double
指针的定义和使用
声明指针变量
什么是指针变量
是用来存放另一个变量的地址(即指针)的变量
例如 int *p;
形式:数据类型类型 +*+指针变量名;
int表示p装的地址对应的空间的数据类型
*表示p是一个指针变量
p指针的名字
指针指向空间
<ul><li>指针就是装地址的变量,变量就要赋值,即一定要装一块空间的地址,或者指向一块空间,才能被使用。</li><li>不装地址的指针以叫<b>野指针。</b><br></li><li>指针变量可以赋值,指针的指向在程序执行中可以改变(例如:指针p在执行中某时刻指向变量x,在另一时刻也可以指向变量y)<br></li></ul><b></b>
初始化
int a = 12;<br> int *p = &a;
赋值(简介运算符_)
int a = 12;<br>int *p; <br>p = &a;
注意点
1.指向是什么意思
装哪块地址,就指向 哪块空间
2.类型一定要对应上
类型决定这指针的读写方式
3.指针<font color="#f384ae">不能</font>与现有变量<font color="#f384ae">同名</font>
4.指针变量的命名规则要与其他<font color="#f384ae">变量命名规则一样</font>
5.指针可以<font color="#f384ae">存放</font>C语言中任何<font color="#f384ae">基本数据类型,数组和其他所有高级数据结构的地址</font>
6.应该指针<font color="#f384ae">指定</font>一个地址后才能在语句中<font color="#f384ae">使用指针</font>
通过指针操作所指向的空间
1.指向其他空间
p = &a;<br>p = &b;
2.通过地址间接操作指向的空间
对内存的操作就三种:读 写 取地址
读
int a = 12;<br>int *p = &a;<br>printf("%d",*p);
输出的*与定义的时候*是一样的
定义的时候属于标记
这个时候是标记运算符、
写
int a = 12;<br>int *p = &a;<br>*p = 12345;<br>scanf("%d",a);
取地址
p就是指向空间的地址,&p是p变量自己的地址
*
内存操作符
3.类型决定内存操作
所指向的空间是什么类型,那么*p就一次操作多大的内存空间
数组元素指针
<font color="#000000">所谓数组元素的指针就是数组元素的地址</font>
数组指针的一些操作
定义数组元素的指针
知识拓展
<b><font color="#000000">在应用数组元素的时候可以使用下标法也可以使用指针法</font><br></b>--<br><font style="font-weight: bold;" color="#000000">下标法</font><font color="#f384ae" style="font-weight: bold;">:</font><font color="#000000" style="">就是使用数组的下标如a[3].</font><br><b style=""><font color="#000000">指针法</font></b><b style="color: rgb(243, 132, 174);">:</b><font color="#000000" style="">就是通过数组的指针来调用数组的数据</font><b style=""><br><font color="#f384ae">---</font><br><font color="#000000">但是指针法占内存少,运行速度高</font></b>
操作
初始化
指向数组
<br>例如:<br>int a[10] = {1,2,3,4,5};<br>int * P = &a或&a[0];<br>
指向数组的元素
<br>例如:<br>int a[10] = {1,2,3,4,5};<br>int * P = &a[1]或a+4;<br>
赋值型
指向数组
例如:<br>int a[10] = {1,2,3,4,5};<br>int * P;<br>p = &a或&a[0];
指向数组的元素
<br>例如:<br>int a[10] = {1,2,3,4,5};<br>int * P;<br>p = &a[1]或a+4;
注意点
数组名不代表整个数组,只代表数组首个元素的地址
引用数组元素时指针的运算
<br>假设p是数组的a[0]<br>可以访问第i个数组元素<br>加i个整数(用+) 例如:p+i;<br>减i个整数(用-) 例如:p-i;<br>--<br>访问下一个元素<br>加等于运算:如p+=;<br>自加运算:如p++,++p;<br>--<br>访问上一个元素<br>减等于运算:如p-=;<br>自减运算:如p--,--p;<br>
指针的大小
内存申请与释放
变量与空间
宏观上分析,多个程序同时执行是什么情况
所有程序/软件的运行,是由操作系统统一调配的,操作系统是程序的运行环境
运行中的多个程序之间,内存是不交叉的
程序结束,操作系统还要释放其使用的资源
微观上分析,就是我们程序里定义的变量,申请的空间(之一)
变量
申请在哪块内存区域?
由谁申请
什么时候释放
由谁释放
比如 int a = 2; int a[23];
过程
数组都是内存的栈区存储
什么是栈(堆栈)区
栈区
特点
内存由系统申请,在变量生命周期结束时由系统释放
生命周期
定义到释放
不时所有的变量在程序结束时(软件关闭时)才释放,服务器为例子
堆区
特点
由我们随时申请,由我们自己随时释放
全局区
字符常量区
代码区
栈区和堆区的对比
栈区变量
由系统申请并释放
分析:也就是程序运行时候,系统要多个任务,就时检测变量时否该释放类了。直白点就是cpu要抽时间执行这部分功能
所以,如果这种变量比较多,不加节制的定义的话,cpu额外的工作量就会加大,程序的运行效率就会降低。
堆区变量
由我们自己申请,由我们自己随时释放
实际运用中
限制我们使用大小,默认大小是1m(不同的编译器是不同的)
stack overflow 爆栈了
堆栈等于栈
默认数值这个大小是可以修改的,但是尽量不要修改。
堆区内存分配(malloc)与释放(free)
malloc'
功能
在堆区申请指定大小的连续的一段空间,并返回该空间的首地址
理论上,32位系统最大申请4G,64位系统最大16tb(由安装内存决定)。<br>
函数原型
void * malloc(size_t size);
举例
int *p =(int *)malloc(4);
int *p<br>p = (int *)malloc(4);
malloc
函数名字
函数参数
要申请的字节数
size_t
32位编译器环境 unsigned int
sizeof size_t 4字节
64位编译器环境 unsigned int
sizeof size_t 8字节
整形表达式
5
无符号后缀是u
2*2
sizeof(int)
写个小数
系统会个你转换成帧数,所以还是写整数
头文件
stdlib.h<br>malloc.h<br>
两个都要写
对申请空间三种情况进行讨论
malloc(正常)
malloc(0)
malloc得到可用空间首地址,0表示该地址起多少个空间可用
malloc(极限)
申请失败返回NULl就是0,没申请到,这个一般内存不够用了
怎么避免
在申请空间时,要在指针前进行判断,并做一些提示
直接使用NULL指针是崩溃的
强制类型转换
(类型*)
malloc就是返回的void*,所以要转换成想要的类型在操作
vs可以不加,有的编译器不加就会报错
定义指针p的使用
*p
所申请的空间无初始化方式
空间全部赋值
使用for循环
例如: for (int i = 0;i<10;I++)<br> {<br> p[i] =0; <br> }
使用函数memset
使用头文件 memory.h
例如:memset(p,1,40)<br>第一个参数:指针名<br>第二个参数:赋值的大小<br>第三个参数:指针空间大小
int a;<br>int *p =&a;<br>*p1 ==a;
int *p2 =(int*)malloc(4); //相当于&a,malloc的空间没有名字<br>*p == 这个空间 //相当于a
注意点
1.千万不能越界
比如要申请四字节当int使用,不能申请三个,但是申请多了也是可以的(不过尽量不要这样)
注意边界
2. 一个指针指向了一块堆空间,千万不也能在指向另一块
会导致内存丢失,造成内存泄露
丢失会继续占用
如果循环就完蛋了
当用一个新的指针记录这个地址后,原来的指针就可以解放
free
函数原型
void free(void *memblock);
释放内存
在我们不用的位置释放内存,如果不释放就一直保存在那
例子
free(p);<br>变量是指针名
返回值
void表示无返回值,主函数void表示无参数,也就是啥都不用管,直接free(p);
参数
要释放的空间指针
注意点
free后的指针,但是空间不能使用
所以,一般指针释放后,赋值一个null;
没有具体指向的指针,叫野指针
不能重复释放同一块空间
不能释放栈区空间
一定要释放头指针
崩溃
运行中的崩溃,一定是某一行具体的代码引起的
运行结束的崩溃,基本就是内存越界操作了,很难查找
至关重要的一点
malloc的空间在程序结束的时候,系统会自动释放所malloc的内存。那为什么还要free()?
服务器会给你重启的机会吗
用户使用软件也不会一直重启
基本数据类型申请
int *p = (int*)malloc(4);<br>short *p1 = (short*)malloc(sizeof(short));<br>float *p2 = (float*)malloc(4);<br>double *p3 = (double*)malloc(8);<br>long *p4 = (long*)malloc(sizeof(long));
子主题
数组malloc的申请
申请一位数组
一维数组的特点
一段连续的空间,数组名字是首元素的首地址
思考
那我们malloc一段空间,然后记住首地址,不就是一个数组了嘛
定义
int* p = (int*)malloc(sizeof(int)*5); 4*5
p第一个元素的地址,p+1就是第二个元素的地址......
定义的时候是初始化的值
malloc不能初始化
可以使用memset赋值成0
赋值成任意值要使用循环
访问
*(p+0) == *p *(p+2) *(p+3) *(p+4)
公式*(p+n) =p(n)
p(0) p(1) p(2) p(3) p(4)
malloc的数组与int a[3]这种栈区数组的区别
使用
定义有点不一样,使用一模一样,free
malloc的数组可任意指定长度
int a;<br> scanf("%d",&a); <br> malloc(a);
可以在运行过程种指定任意大小
动态数组,动态分配空间
int a[2]; 就不一样了,个数在定义时候确定,以后就不能修改
虽然又变长数组的标准,但是支持的编译器不多
只要定义好了,这个p就是跟二维数组的int a[2]的a一模一样,千万不能越界
一维数组指针接这个空间
int (*p)[5] = (int(*)[5])malloc(4*5);
可类比一维数组
int a[5];<br> int (*p)[5] = &a;
那么
*p == a
所以
访问
*(p+0) ==** p *(*p+1) *(*p+2) *(*p+3) *(*p+4)
公式 *(*p+n)=(*p)[n]
(*p)[0] (*p)[1] (*p)[2] (*p)[3] (*p)[4]
二维数组指针接这个空间
int(*p)[2][3] = (int (*)[2][3])malloc(2*3*4);
可类比一维指针
int a[2][3];<br> int (* p )[2][3] = &a;
*p ==a
访问
*(p+0) ==** p *(*p+1) *(*p+2) *(*p+3) *(*p+4)
公式 *(*p+n)=(*p)[n]
(*p)[0][0] (*p)[0][1] (*p)[0][2] (*p)[1][0] (*p)[1][1] (*p)[1][2]
calloc realloc
功能
申请一段空间数组
void *calloc(size_t num,size_t size);
例子
int *p =(int *)calloc(5,4);
头文件
<stdlib.h>和<malloc.h>
特点
每个元素会被初始化成0
*的四种作用
声明的时候有*,表示指针变量
*+地址,表示地址操作符
数字*数字 表述乘法
注释
函数类型
函数类型用来定义函数,描述一个函数的接口,包含函数<font color="#f384ae">返回值的数据类型</font>和<font color="#f384ae">参数的类型</font>
构造类型
数组([])
含义
就是一组具有<b><font color="#c41230">固定数目</font></b>的、<font color="#c41230">有序的、类型相同</font>的数据的集合。<br>根据<b>数组下标的多少</b>,数组可以<font color="#c41230">分为一维数组和多维数组</font>。 <br>
图片
一维数组
格式
数据类型 数组名[常量表达式]
数据类型:任一种<font color="#c41230">基本数据类型</font>或<font color="#c41230">构造数据类型</font>
数组名:用户自定义的数组名字,<font color="#c41230">其定名规则与变量名定名规则一样</font>,都需遵循标识符定名规则 <br>
常量表达式:表示<font color="#c41230">元素</font>的<font color="#c41230">个数</font>即<font color="#c41230">数组长度</font>
[]:下标运算符单目运算符<br>优先级(1)<br>左结合<br>不能用( )
数组的初始化
完全初始化
就是定义的时候就给所有的空间进行赋值
int a[5] = {1, 2, 3, 4, 5};
<b><font color="#c41230">int a[] = {1, 2, 3, 4, 5};<br>可以不写常量</font></b>
部分初始化
只使用了一部分空间
int a[5] = {1, 2};
使用输入函数
通过手动键盘输入赋值
# include <stdio.h><br>int main(void)<br>{<br> int a[5] = {0}; //数组清零初始化<br> int i;<br> printf("请输入5个数:");<br> for (i=0; i<5; ++i)<br> {<br> scanf("%d", &a[i] );<br> }<br> for (i=0; i<5; ++i)<br> {<br> printf("%d\x20", a[i]);<br> }<br> printf("\n");<br> return 0;<br>}
使用表达式赋值
int a[10] = {1,2,3,4,5}<br>a[4]=a[3]+2; <br>
数组的使用
数组必须<font color="#c41230">先定义,然后使用</font>。
数组元素的表示形式为:数组名[下标]<br>--<br>下标可以是<b><font color="#c41230">整型常量或整型表达式</font></b> <br>
C语言规定只能<b><font color="#c41230">逐个引用</font></b>数组元素而<font color="#c41230"><b>不能一次引用整个</b></font>数组
注意
数组名不能与其它变量名相同
不能在方括号中用<b><font color="#c41230">变量</font></b>来表示<font color="#c41230"><b>元素的个数</b></font>,但可以是<b><font color="#c41230">符号常数或常量表达式</font></b>
#define FD 5<br> void main()<br> { <br> int a[3+2],b[7+FD];<br> ……<br> } <br>
方括号中<b><font color="#c41230">常量</font></b>表达式表示数组<font color="#c41230">元素的个数</font>。<br>如int a[5]: 数组a有5个元素,其下标从0开始,分别为a[0],a[1],a[2],a[3],a[4]。
允许在<b><font color="#c41230">同一个类型</font></b>说明中说明<b><font color="#c41230">多个数组和多个变量</font></b>。<br>例如:<br> int a,b,c,d,k1[10],k2[20]; <br>
结构体类型(struct)
共用体类型(union)
枚举类型(enum)<br>空类型(void)
<p><b>算术类型(Arithmetic Type)</b>:可以做<font color="#f384ae">算术运算的类型</font>。包括<font color="#f384ae">整型、浮点型,枚举</font>。</p>算术类型可以表示为0和非0,作为控制表达式。
<b>标量类型也叫纯量类型(Scalar Type)</b>:可以<font color="#f384ae">参与逻辑运算(与或非)</font>,或者做控制表达式的类型。包括<font color="#f384ae">算术类型和指针类型</font>。
<b>组合类型(aggregate type)</b>:在同一时间内<font color="#f384ae">只有一个成员具有值</font>。包括<font color="#f384ae">数组类型,结构体类型</font>
函数
0 条评论
下一页