c语言
2021-12-31 21:24:56 60 举报
AI智能生成
C语言基础
作者其他创作
大纲/内容
C语言入门
C语言程序
程序代码的组成
头文件
main()函数
程序的组织结构,是被各个编译系统公认的起点
函数
定义:是一个能独立实现某种特定功能的程序模块
组成
函数首部:a.函数类型 b.函数名 c.参数
函数体:由{和}括起来的多条语句组成
注意
程序可以包含一个或多个函数
程序有且仅有一个main()函数
函数由多条语句构成,且每条语句用“;”结束
函数分为用户自定义函数和系统库函数
C语言程序的开发与运行
开发
编写程序
注释
采用“/*...*/”格式
采用“//”格式
编译程序
编译器:是介于用户和计算机之间的一个软件系统,将某种语言编写的源代码转换成能被计算机识别并运行的指令代码
连接程序
运行程序
运行
计算机存储程序原理
冯诺依曼
计算机程序是按顺序进行的
程序和数据总是驻留在内存中
数据类型
数据类型分类
基本数据类型
整型(int)
按长短分
短整型(short int) 2字节
基本整型(int) 4字节
长整型(long) 4字节
按正负分
有符号整型(siighed)
无符号整型(unsighed)
字符型(char)
浮点型(float和double)
构造类型
数组类型
结构体类型(struct)
共用体类型(union)
枚举类型(enum)
指针类型
用(*)标记的类型
空类型
void
基本数据类型
标识符
定义:在程序中,标识符是用来标识变量名、符号常量名、函数名、数组等操作对象的名称;在内存中,表示某个被使用的存储单元
分类
系统定义标识符,不可更改
用户自定义标识符:由数字、字母和下划线组成
常用的转义字符
\0 字符串结束标志
\n 回车换行
\t 跳到下一个输出位置
\r 回车,光标回到本行开头,但不换行
\b 退格,将当前位置移到前一列(擦掉经过字符)
\ddd ddd为1到3位八进制数所代表的字符
\xhh hh为1到2位十六进制数所代表的字符
字符
字符常量
字符串常量
用双引号括起来的字符序列 ,由多个字符组成,且系统默认用\0作为字符串常量的结束符 “china”
区别
表示方式不同:字符常量使用单引号;字符串常量使用双引号。如‘a’和“a”
长度不同:字符常量的固定长度为1,;字符串常量的长度既可以为0,也可以是其他整数值
内存单元大小不同:字符常量只分配一个字节用于存储该字符;字符串常量要开辟多个空间用来存储所有字符和最后的结束符‘\0’
浮点型常量
分类
单精度 float 4字节
双精度 double 8字节
表示方式
十进制小数形式 12.5f 0.123
科学计数法(指数形式:指数形式是由<尾数>E(e)<整形指数>三部分构成 2E-5(2*10^-5 ) 1E4(1*10^4)
强调尾数可以是整数或小数; 整数指数必须是整形常量,且为时间禁止形式; 指数和尾数都不能
注意:如果浮点型数据没有指明具体精度类型,编译器默认是双精度D(d)型。 如0.123属于double型。同时还可以使用后缀来标记该数值具体属于哪种精度类型,如F(f)单精度。
数据类型的转换
规则:若两种不同类型的数据运算,就要发生数据类型的转换
分类
1.系统自动转换
a.先转换后运算
b.转换时遵循将精度低、表示范围小的数据转换成精度高、表示范围大的数据
精度高低顺序由低到高为:整数(short、char、int、long)类型、浮点(float、double)类型
数据转换规则
2.强制类型转换
(类型)表达式
数据的输入输出
输入:从指定设备上读入数据到程序中;输出:从程序中取出数据输出到设备中
分类
按工作原理
带缓冲区
单个字符的输入/输出getchar()/putchar()
有格式的数据输入/输出scanf()/printf()
scanf格式控制符
附加
printf格式控制符 同scanf
字符串的输入输出gets()/puts()
不带缓冲区
运算符与表达式
运算符介绍
按操作数分
单目运算符(只有一个操作数)
!(逻辑非)
~(按位反)
++(自增)
--(自减)
双目运算符(有两个操作数)
算数
关系
逻辑
赋值
位运算符
三目运算符(有三个操作数)
按功能分
算数
关系
逻辑
赋值
位
条件
逗号
算术运算符和算术表达式
单目运算符
自增(++x)自减(--x)
++x、--x先自增自减在应用
x++、x--先应用在自增自减
正(+)负(-)
双目运算符
加减乘除运算符
取余运算符
两侧的操作数类型必须是整数类型
具有左结合性,余数符号与分子符号一致
算术表达式(使用算术运算符和括号将操作数连接起来,并符合C语言规则的式子)
优先性和结合性
优先级:运算的先后顺序
结合性:选择选择先于左边结合还是先于右边结合
逻辑运算符和关系表达式
逻辑运算符
!、&&、||
右结合性
逻辑表达式(使用逻辑运算符将操作数连接起来,并符合C语言规则的式子)
关系运算符与关系表达式
运算符(>、>=、<、<=、==、!+)
结果为真或假
左结合性
关系表达式(使用关系运算符将操作数连接起来,并符合C语言规则的式子)
赋值运算符和赋值表达式
赋值运算符
=、+=、-=、*=、/=、%=、&=、!=、^=
右结合性
赋值表达式(使用赋值运算符将操作数连接起来,并符合C语言规则的式子)
数据类型转换
位运算符
单目运算符
~(按位取反)
双目运算符
&、^、|、<<、>>
右结合性
其他运算符
条件运算符
逗号运算符
计算所占内存空间运算符
取地址符
用户需求
选择结构
简单if选择结构
结构格式 if(表达式) {条件语句}
流程图
if ...else 选择结构
结构格式 if(表达式) {条件语句1} else {条件语句2}
流程图
注意:a.if后不能加分号,若加了则只表达判断,后面都执行;b.if后若只有一条语句,则可以不适用{},否则必须使用{}将多条语句括在一起,构成复合语句,若不使用,则条件体仅到第一个分号结束。
if ...else if...else选择结构
语法格式 if(表达式1) {条件语句1} else if(表达式2) {条件语句2} else {条件语句n}
流程图
if选择结构的嵌套
简单嵌套格式
子主题
复杂嵌套格式
子主题
注意:在多重if...else 结构嵌套中,if与else的匹配原则是:else总于离他最近的if(或else if)关键字配对
switch case 多分支选择结构
Switch case选择结构格式
Switch case结构注意事项
a. Switch(表达式)中的表达式部分,ANSI C标准中规定允许使用任意类型,但必须与常量值类型相一致
b. 在case和常量值之间一定要留有空格,否则有语法错误
c. 多个case中的常量值必须互不相同,否则会出现语法错误
d. case和default后面的“条件体语句”中,如果有多条语句,则可以不使用‘{}’构成复合语句
e. 当Switch(表达式)中的表达式值与case中的常量值i相等时,则从第i个位置开始顺序向下执行,直到最后、
f. default可以写在switch内的任意位置,也可以省略不写
break语句跳出此次switch结构
switch case嵌套结构
循环结构
基础
概念:为了实现某一结构而反复执行某种操作的程序控制方法。
关键要素:初值、结束条件、循环体、步进
while循环结构
语法结构
流程图
注意
a. 循环体中有些条件可以省略
b. 若循环体中有许多句,必须将循环体放入{}内,构成复合语句块
c. 循环体制,语句的先后位置必须复合逻辑,否则会影响运算结果
d.循环体中必须有使循环趋向结束的操作,否则将陷入死循环。一般情况下,利用步进朝着结束条件方向行进
确定循环结束条件
定义循环变量法
设定某个控制变量法
do while循环结构
语法结构
流程图
注意:第一次执行循环时不用判定循环条件,只有第二次执行循环体前才判定循环条件,因此,不管循环条件真与假,循环体至少都要执行一次
do while与while的区别
do while先执行循环体在判断条件,循环体至少循环一次。
while 语句先判断条件再执行循环体,循环体有可能一次也不执行
for循环结构
语法结构
语法结构变化
1. 省略表达式1(循环初值)。如果此时还需要初值,可以将其放在循环体外。注意:省略初值,但不可省略“;”
2,。 省略表达式2,此时意味着循环条件永远为非0(逻辑真)。因此,循环体内必须有使循环结束的条件,否则将陷入死循环 此时for循环与while循环等价
3. 省略表达式3,如果还需要使用步进,可以将其放在循环体内。
流程图
总结
1. 在三种循环结构中,如果循环语句包含一条以上的语句,应用“{}”括起来,构成复合语句
2. 循环体语句的先后顺序必须符合逻辑,否则会影响运算结果
3. 必须有循环趋向结束的操作,否则将陷入死循环
break和continue关键字
break
一般适用于switchcase多条件选择结构
功能:在循环条件仍为真的情况下,提前结束循环,然后执行循环体之外的程序
continue
只适用于循环结构
功能:在循环条件仍为真的情况下,仅让本次循环提前结束,然后继续执行新的下一次循环
函数
函数的定义
概念:定义函数即相当于创建一个具有某种特定功能的盒子模型。一般要具有输入、输出和符合逻辑的内部实现结构
基础要求
1. 掌握函数的构成格式
函数头部
函数类型(函数返回值类型)---函数的输出口
1、若函数类型与计算结果类型不一致,应与标注的函数返回值类型为准
2、一般情况下,只有在需要将函数某计算结果返回给使用该函数的主调函数时,才标出相应的函数类型,同时在函数体内使用return关键字语句
3、计算结果自己用,不需要标注确切的返回类型,用void函数无返回值
函数名
参数列表(形式参数)---函数的输入口
函数体
使用“{}”括起来的多条语句
return关键字
格式:return 返回值;
作用
1、该函数被调用时,将函数计算结果返回给主调函数,但仅返回一个值
2、提前结束函数运行。
2. 掌握函数体内实现某一特定功能的算法
eg:
函数的调用
优点
1、程序结构简单,层次分明
2、程序结构易于维护,可扩展性好
3、程序功能上分而治之,分工协作
注意:函数定义时使用的是形式参数,函数调用时使用的是实参,实参与形参之间按位置顺序一一对应传值
函数的声明
函数的声明仅解决函数定义与函数调用之间位置关系不匹配的问题,如果在函数使用之前没有函数的定义,则必须在使用位置之前进行函数的声明
声明格式
函数的分类
从用户对函数的使用形式分类
系统库函数
用户自定义函数
从函数的参数形式分类
无参函数
有参函数
从函数的返回值类型
带返回值
无返回值
void空类型
函数的递归
函数的嵌套调用
在函数执行过程中,函数体内又调用另一个函数的过程
注意:函数体内只能嵌套调用其他函数,不能嵌套定义其他函数
函数的递归调用
在一个函数体内直接或间接地又调用了函数自身
条件
1、函数所解决的问题必须能划分为多个同类型的子问题,每次递归调用自身相当于解决一个子问题。同时,递归调用时,函数传递的实参值必须要逐步向结束条件方向靠近
2、函数体内必须有使子问题趋于结束的条件,否则递归调用将陷入死循环
eg:n=n*(n-1)
全局变量和局部变量
全局变量
概念;定义在函数外部的变量称为全局变量(外部变量)
局部变量
概念:定义在函数内部、函数参数列表或某些代码段中的变量称为局部变量
区别:适用范围不同
局部变量仅限于本函数内部或某代码段内部
全局变量从变量的定义行到本文件尾。若要在其他文件中使用全局变量,则需要使用extern关键字进行声明
局部变量没有默认的初始值,需要用户自定义赋值,而全局变量会有默认的初始值0
存储类别
auto(自动)
auto存储类别表明该类别变量是被存储在动态存储区中
动态存储区特点:当需要在这个区域为变量分配空间时,系统自动分配存储空间,变量使用结束后系统会自动收回该空间,释放该空间中变量值
系统不会为该类别变量设定默认初始值,需要用户自定义
使用格式:auto 类型 变量名;
只用于修饰局部变量
static(静态)
static存储类别表明该类型变量是被存储在静态存储区中
静态存储区特点:一旦在这个区域内为变量分配了存储空间,则空间永不释放,直到程序运行结束
系统会默认初始值为0
使用格式:static 类型 变量
可以修饰局部变量也可以修饰全局变量
静态全局变量仅可以在本文件中使用
register(寄存器)
register存储类别表明该类别变量是被存储在CPU的寄存器中
该类别变量不设默认初始值
使用格式:register 类型 变量名
只用于函数内部的局部变量和函数的参数可以声明为register
直接从CPU寄存器中取数据,而不是从内存中取数据。可以提高程序运行效率
external(外部)
仅能修饰全局变量和函数
使用格式:extern 类型 变量名
数组
数组的引入
数组是将多个具有相同类型的数据组合在一起,构成一个整体,
子主题
分类
根据存储数据的类型不同
整形数组
浮点型数组
字符型数组
根据数组空间维数的多少
一维数组
定义一维数组时,需使用某种合法的数据类型和“【】”运算符
定义格式
类型 数组名 [常量或常量表达式]
eg:float score [30]
score表示首元素的地址(位置);score+1表示下一个元素所在的地址
一维数组的内存表示
子主题
下标值是一个相对量,是指某个元素相对于首元素的偏移量。因此,数组中的第一个元素的下标值为0,第二个为1,往后依次排列为2、3...、29
数组存储后,在存储空间中有两个值,一定不能混淆。其一是存储单元的地址;其二是存储单元的内容
初始化赋值
1、为数组中所有元素赋值 。eg:int a[5]={9,8,7,6,5};
2、为数组部分元素赋值 。eg:int a[5]={9,8,7}; //数组前三个元素为987,其他两个值默认为0
4、定义数组时,如果直接为数组元素进行初始化赋值,则数组长度可以省略。 eg:int a[]={1,2,3,4,5} //数组中元素的个数默认为0.
下标法
1、使用下标法为数组元素赋值
score[0]=60.5
2、使用下标法取数组元素值
d1=score[0]
3、使用下标法表示数组中每个元素的地址
score+0
起泡排序
在每趟排序中依次比较数组中两个相邻元素值,逐步将最大的移至最后
子主题
选择排序
一个一个比较完,最后一步将最小的移至最后
子主题
二维数组
定义二维数组时,需要使用某种合法的数据类型和“[][]”运算符,第一个指数组的行数;第二个指数组的列数
定义格式
类型 数组名[行常量表达式][列常量表达式;]
表示地址
行地址表示形式
a+0、a+1
列地址表示形式
a[0]+1、a[0]+2
元素值
a[0][1]
初始化赋值
1、按元素在内存中排列顺序依次为二维数组元素赋值
eg: int a[2][3]={9,8,7,6,5,4};
2、按数组行列形式赋值,每行需要用{}括起来
eg : int a[2][3]={{9,8,7},{6,5,4}}
3、为数组中部分元素赋值
eg: int a[2][3]={{5},{2}} ; //数组中每行第一列元素都有值,其他元素值都默认为0
4、定义数组时,如果直接为数组元素进行初始化赋值,则二维数组行的长度可以省略,但列的长度不能省略
eg: int a[][3]={2,3,4,5,}
注意
一维数组和二维数组都可以做函数的参数,在函数被调用时实参与形参之间传递的是地址
字符数组
在定义字符数组时,使用char类型和"[]"运算符
定义格式
char 数组名 [常量或常量表达式]
初始化赋值
1、用单个字符常量为字符数组初始化赋值
eg: char str[5]={'a','b','c'}; //数组后两个默认为‘\0’
2、用字符串常量为字符数组初始化赋值
char str[5]={"efgh"}; //只能用于长度小于4的字符串常量
3、定义字符数组并直接为数组元素初始化赋值
char str[]="abcdefg"
输入输出
%c按单个字符
%s按字符串
直接使用gets()puts()
gets(str)
字符串处理数组
1、字符串输出函数puts
puts (char str[])
2、字符串输入函数gets
gets (char str[])
3、字符串连接函数stract()
stract(char str1[], char str2[])
4、字符串复制函数strcpy()
strcpy(char str1[], char str2[])
5、字符串比较函数strcmp()
int strcmp(char str1[],char str2[])
6、求字符串长度函数strlen()
strlen(char str [])
7、大写字母转换为小写字母函数strlwr()
strlwr(char str[])
8、小写字母转换为大写字母函数strupr()
strupr(char str[])
预处理命令
目的:为提高程序代码的编写效率和程序的运行效率
预处理命令时必须在开头加上“#”,且结尾处不需要使用“;”作为结束符。
预处理
宏定义
概念:指用指定的标识符来代表给定的字符串
优点:可以减少程序中较长且复杂字符串的重复书写,简化了程序代码的书写过程
使用形式
不带参数的宏定义
#define 标识符 字符串(标识符又称为宏名,宏名一般使用大写字母)
eg:#define PI 3.14159
带参数的宏定义
#define 标识符 (参数列表) 字符串 (字符串中包含参数列表中给定的参数)
eg:#define S(x) x*x
注意
a. 宏名用大写
b. 宏名在编译前仅仅用指定字符串替换,不进行任何运算处理
c. #define可出现在程序的任意位置,但最好写前面。宏定义后,宏名有效范围从定义位置开始,直到本文件尾。若想提前结束宏定义可使用:#undef宏名。
带参数的宏替换与函数调用的区别
执行时间不同
带参数的宏替换是在编译之前被执行
函数调用是在编译之后程序运行期间被执行
处理的方式不同
带参数的宏替换在执行时不做任何运算处理,仅仅是用字符串的原样替换宏名,同时进行参数替换
函数调用需先计算实参值,然后将计算结果传递给形参
占用内存空间不同
带参数的宏替换在执行时不需要开辟任何存储空间仅做字符串的替换
函数调用需要给形参变量开辟新的存储空间
文件包含
定义格式#include <头文件名>
查找方式不同
#include <stdio.h>
安装路径下的\INCLUDE\目录中查找指定的头文件
用于包含系统库函数的头文件
#include "stdio.h"
先在用户当前的工作目录中查找指定的头文件,如果找不到,则在到安装路劲下的\INCLUDE\目录中查找
用于包含用户自定义的头文件
条件编译
概念:指根据给定的条件来选择要编译的内容
分类
#ifdef
1. ifdef简单形式
#indef宏名标识符 ...程序段1 ... #endif
2. ifdef...else形式
#ifdef 宏名标识符 ...程序段1... #else ...程序段2... #endif
功能:如果宏名标识符已经被#define定义过,则编译程序段1,否则编译程序段2
#ifndef
ifndef简单形式
#ifndef 宏名标识符 ...程序段1... #endif
ifndef...else形式
#ifndef 宏名标识符 ...程序段1... #else ...程序段2... #endif
功能:.
如果宏名标识符未被#define定义过,则编译程序段1,否则编译程序段2
多被用于防止某个变量、函数重复定义或头文件内容的重复包含的情况
#if
if简单形式
#if 表达式 ...程序段1... #endif
if ...else 形式
#if 表达式 ...程序段1... #else ...程序段2... #endif
功能:如果表达式为逻辑真(非0),则编译程序段1,否则编译程序段2
指针
指针的引入
用指针类型定义的变量称为指针变量
定义:指针变量是专门用拉埃保存内存单元地址的一种变量。
使用:
a.定义一个指针变量
b.为指针变量初始化赋值
c.指针法操作内存单元的内容
指针的分类
指向单个变量的指针
赋值
p1=&a(利用取地址运算符获取a变量的地址值并赋给p1)
p2=p1(更改p2的指向关系)
*p=20(向p所指向的的内存单元赋值)
子主题
指向数组元素的指针
在一维数组中,用一维数组名表示首元素的地址
在二维数组中,二维数组名仅表示首行的地址
赋值
p=&a[1][2]---适用取地址符
p=a[0]+0---使用数组名表示的数组元素 列地址
行地址与列地址的转换
行地址转换为列地址
在二维数组的行地址前加*
列地址转换为行地址
在二维数组的列地址前加&
指向一维数组的指针
赋值
p=&a[3] ---使用取地址符
p=a+3----使用数组名表示的元素地址
指向一维数组的指针变量(行指针)
指向整个一维数组(或二维数组中的一行)
格式
数据类型 (*指针变量) [m]
指针数组
把多个指针合成一个数组
指向函数的指针
指针变量中存放的是函数的入口地址
定义格式 数据类型 (*指针变量名) (函数参数列表)
int (*p_max)(int,int)
返回类型为指针型函数
函数的返回类型是指针型
定义格式 数据类型 *函数名(函数参数列表)
int *fun()
指向字符串的指针变量
格式 char *指针变量名
字符指针变量与字符数组的区别
字符指针是一个变量,可以用赋值运算符“=”为其赋值。字符数组的数组名是一个常量,不可以使用赋值运算符“=”为其赋值,赋值时只能使用字符串处理函数strcpy()。
char *p; p="abcd";
char st[10]; strcpy(st,"abcd")
字符指针变量作为一个变量,仅完成对字符串的指向。因此,定义字符指针时仅会开辟一个固定大小(4B)空间存放指针变量。而字符数组是用来存放字符的数组,当声明字符数组时,会在内存中开辟数组长度大小的内存空间,用于存储数组中的所有字符。
0 条评论
下一页