华清•C语言基础笔记

1、选择开发环境

选择Linux分支下的Ubuntu操作系统作为学习C语言的开发环境

1.1 环境安装:

a、Ubuntu Linux.7z----------虚拟机系统

b、VMware:VMware  Workstation 16 Pro 激活密钥.txt ; VMware-workstation-full-16.1.0-17198959.exe------虚拟机软件

c、参照安装VMware虚拟机.pdf----安装文档

d、安装Ubuntu后,在虚拟机软件中启用ubuntu系统:Ubuntu Linux.7z--解压后打开

e、C语言开发环境:ubuntu系统---->终端(terminal)

1.2 相关名词

程序:解决完成特定功能(任务)的流程步骤

计算机程序:让计算机去实现解决问题的步骤执行

计算机语言:计算机能够识别任务的内容(指令)

机器语言:使用0和1表示指令功能

汇编语言(助记符语言):把机器指令用助记符进行表示

高级语言:类似自然语言的编写方式

C语言:高级语言,适合嵌入式开发

1.3 C语言程序的编写编译

Linux中编写C语言程序的工具:

vim工具:在终端上编写文本文件内容--可用vim用来写程序代码,是一种多模式的文本编辑器

vim:只是编辑器,类似于windows记事本,只负责写文本内容(程序内容)

vim终端的文本编辑器:用于创建、显示、编辑文本

vim操作命令:

vim:打开vim编辑

vim + [xxxx文件名]:打开xxxx文件,如果文件名不存在,则创建一个新文件(临时)

1.4 Vim基本操作

vim工作模式:命令模式,插入模式,底行模式

命令模式与插入模式:i,a,o进入,Esc退出

命令模式与插入模式:Shift+:进入,删除:退出或回车执行命令退出

1.4.1 插入模式命令

(1)字符插入:
a:在光标所在字符之后插入

A:在光标所在行尾插入

i:在光标所在字符之前插入

I:在光标所在行首插入

o:光标所在下一行插入

O:光标所在上一行插入
(2)光标定位:
gg:回到文首

GG:去到文末(尾行文首),等价于“]]”

nG:跳转到第n行行首

0:跳转到当前行首

$:跳转到当前行尾

b:跳转到前一个单词词首

w:跳转到下一个单词词首
(3)复制、粘贴、删除:
yy:复制光标当前行

nyy:复制从光标开始的n行,包括光标所在行

p:粘贴n行到当前光标所在下一行(新建一行粘贴)

dd:剪切光标所在行

ndd:剪切从光标开始的n行,也可用作删除

x:删除光标所在位置的字符

nx:删除光标所在位置前n个字符

nX:删除光标所在位置前n个字符

dG:删除光标所在行开始到整个文件末尾

u:恢复,撤销

1.4.2 命令模式

(2)底行命令:
:n:跳转到第n行行首

:set nu:显示行号,set number

:set nonu:不显示行号

:n1,n2d:从n1行开始删除到n2行结束
(2)保存退出命令:
:x!:强制保存并退出,等价:wq!

:a:所有文件,用例如wqa,xa
(3)查找替换命令:
:/+[查找内容]:查找光标后的指定内容

:\+[查找内容]:查找光标前的指定内容

:n:继续查找下一个,N:继续查找上一个

:%s/+[查找内容]/+[替换内容]:全文替换,如:%s/old/new代表把全文old替换为new

:n1,n2s/old/new:把n1到n2行的old替换为new

r:用输入的字符替换光标所在的字符

R:从当前行开始,用输入的字符替换光标所在的字符

:w:保存当前文件

:w + [文件名]:把当前文件以文件名保存一份,备份(另存为)

:q:退出当前文件

:q!:强制退出

:x:保存且退出,等价:wq

:q!:强制退出

:x(!):(强制)保存且退出,x == wq

:a:所有文件
(4)搜索替换命令:
/:查找内容,从当前光标位置开始查找对应内容,n:查找下一个,N:查找上一个

:%s/old/new:全文替换指定字符串,%s:代表全文,把old 替换为 new

:n1,n2s/old/new:从n1行开始到n2行结束,把old替换为new

r:替换光标所在位置的字符,然后输入的字符就是替换的字符

R:从当前光标开始,使用输入的内容替换当前行的内容 
(5)其他命令(编译执行)
编译:把C程序翻译为计算机能够认识的指令(01机器程序)

gcc:gcc  xxx文件名----->编译:进行对应的转换,生成一个编译好的(计算机能够识别,执行的程序):a.out

执行 可执行程序:./a.out

大神级编辑器:Vim(Linux)、EMACS(macOS)

2、C基础语法–关键字与标识符

2.1 C语言的关键字与标识符

2.1.1 关键字:32个

auto:
double:
int:
struct:
break:
else:
long:
switch:
enum:
register:
typedef:
char:
extern:
return:
union:
const:
float:
short:
uns i g:ned
continue:
for:
signed:
void:
default:
goto:
sizeof:
volatile:
do:
while:
static:

2.1.2 标识符(自定义的关键字,由“A-Z,a-z,0-9,_”构成,且只能以字母或下划线开始)

驼峰命名法:第一个单词小写,后面每个单词首字母大写,或者使用下划线分割的方式,如userName,user_name,可用站点:chtml.cn

合法标识符:abc,a1,a2,o_k

非法标识符:%abc,a$b,1a

2.1.3 例题:求闰年问题(被4整除和被100整除)

3、C语言基础语法–数据类型

在C程序中,存在数据,每种数据都有对应的数据类型,数据类型有:整型、实型、字符型、枚举,数组(包括字符数组)、结构体、共用体,指针以及空类型

3.1 基本类型

3.1.1 整型(int)

(有符号signed、无符号unsigned):如10,-10,1,-101,另外signed在二进制中以第一位赋0表示正数,第一位赋1表示负数

(1) 整数的进制与转换

进制转换:

十进制转二进制:短除法,除以2取余数,余数从低位到高位依次表示

二进制转十进制:乘以权值再相加

进制的表示:

十进制:常量中包含0~9,但是一定不能以0开头

八进制:只包含0~7,而且必须以0开头

十六进制:包含0~9和a~f,总是以0x开头

另外,在编译器中,15L或0377l可以强制把常量作为长整数,15U或0377u可指明成无符号常量,15LL或0377ll可以强制转换成long long int型

(2) 整型的分类
符号之分:有符号整型(signed)与无符号整型(unsigned),有符号数中,最高位作为符号位,用0表示正数,用1表示负数

大小之分:短整型(short int)、整型(int)、长整形(long int)、超长整型(long long int,C99中新增),除了整型int,其他三个在使用时可以省略int关键字

数的存储:计算机中存储数据都是以 补码 格式存储

原码:数据的二进制格式

反码:正数的反码 = 原码;负数的反码 = 原码除符号位外,按位取反

补码:正数补码 = 原码,负数补码 = 反码 + 1
(3) 整型的存储

整型在计算机中以二进制的补码形式存储,各整型所占大小为:

整型:根据在计算机中设定的大小有

short (int):短整型------16位二进制(16bit),2B

int:整型-------------32位(32bit),4B

long (int):长整型-------在32位系统大小为 32位(32bit),4B ;在64位系统大小为 64位(64bit),8B

long long (int):超长整型----64位(64bit),8B

有符号数:

(signed):有符号数,最高位为 符号位

无符号数:

unsigned:无符号数,没有符号位

32位无符号整数:unsigned int

16位有符号整数:signed short int--------->short

3.1.2 实型(浮点型)

(单精度float、双精度double):如1.2,3.1415,-1.2

浮点型存储:二进制,补码形式存储,数据部分 + 指数部分

(1)C语言浮点类型按精度不同划分:
float:单精度浮点型---32位(32bit),4B,精度:6/7;符号位:1bit;阶码:8bit;尾数:23bit

double:双精度浮点型-----64位(64bit),8B,精度:15/16;符号位:1bit;阶码:11bit;尾数:52bit

扩展精度浮点数(long double):80位或128位

3.1.3 字符型char:‘a’,‘#’,‘0’

对于字符型数据,在计算机中存储,依旧使用二进制 0 和 1表示,对于每个字符统一用一种标准的二进制来表示

在C语言中,使用 ASCII码来表示(小整数)

字符"0":48

大写A:65

小写a:97

存储的字符对应ASCLL码,ASCLL码就是整数,以二进制存储

char:字符类型—8位(8bit),1B(字节)

字符类型可以当做整数进行操作


以下属于C高级

3.1.4 枚举类型enum

3.2 C高级数据类型:

3.2.1 构造类型(C高级)

(1)数组类型(字符串)
(2)结构体类型struct
(3)共用体类型union

3.2.2 指针类型(C高级)

3.2.3 空类型(C高级)

以上属于C高级内容


3.3 变量与常量

常量:在整个程序中都不会进行改变的数据

变量:在整个程序中可以进行变化的数据,在内存中存储数据后,空间中的数据值可以进行改变

变量定义:必须先定义变量,才能使用

存储类型 数据类型 变量名;

变量名:使用标识符来表示(相当于赋予了变量数据的含义)

3.3.1 存储类型:

auto:默认类型,通常可以省略,表示定义在栈区

static:静态类型

register:寄存器类型,不一定能存储到cpu中,未存储到CPU中则等价auto自动分配类型

extern:外部类型

3.3.2 变量初始化

在定义变量时,为变量赋初值

#include<stdio.h>

int main()
{
	auto int a;	// 默认类型
	static float b;	// 静态类型
	register char c;// 寄存器类型,未存到内存中则等于auto

	double d;	// 定义双精度浮点型,auto

	int a1,a2,a3;	// 连续定义同种类型 int 的三个变量
	
	float e = 3.14; // 定义单精度浮点型

	//初始化变量a,将a变量存储4
	a = 4;	// 赋值运算,使用“ = ”进行赋初值

	a1 = 4;
	a1 = a;	// 只要使用变量名就是使用变量数据

	printf("hello world\n");

	printf("a = %d\n" ,a);

	int x1 = -20;
	short x2 = 10;
	unsigned long x3 = 30;

	printf("%d,\n%hd\n",x1,x2);
}

输出结果:

ubuntu@linuxmachine:~$ gcc 1.c
ubuntu@linuxmachine:~$ ./a.out
hello world
a = 4
-20,
10

4、C基础语法—输入输出

4.1 输出-打印

printf:由C语言标准所设计的输出功能,只要使printf就可以实现输出打印(终端)

printf功能包含在stdio.h中,所以要使用的话#include<stdio.h>

格式:printf("要输出打印的内容 格式化字符1,格式化字符2");

4.1.1 格式化打印字符:

%m.p格式字符:m 数据的宽度,p小数的精度

d 或 i :以带符号的十进制形式输出整数(正数不显示+),i 是老式写法,现多用 d
u :以无符号的十进制形式输出整数
hd 或 ld 或 lld :分别以短整型 short、长整型 long、超长整型 long long 输出
o :以八进制无符号形式输出整数
X 或 x :以十六进制无符号形式输出整数,x 表示十六进制的a~f小写,X 则 A~F大写
f :以定点十进制小数形式输出浮点数
E 或 e :以指数形式输出十进制浮点数,e 表示 e 小写,E 表示 E 大写
G 或 g :根据数值自动采用 f 或 e 方式输出,区别在于会自动省去尾随的 0 或小数点,默认精度为 6
c :以字符形式输出,只输出一个字符
s :以字符串形式输出
p :输出指针的值或变量的地址值

4.1.2 格式化输出控制标志Flags

- :(负号) 输出内容左对齐
+ :(正号) 在正值之前显示加号,在负值之前显示减号
空格:在未使用 + 标志打印的正值之前打印空格
#:对于八进制数前面添加 0
#:对于十六进制数前面添加 0x 或 0X
#:若使用的是 g 或 G,则尾随的 0 不被消除
0 :(零) 在前面用 0 填充空格

4.1.3 格式化输出转义字符

字符 功能说明 ASCII
\a :响铃(BEL) 007
\b :退格(BS) ,将当前位置移到前一列 008
\f :换页(FF),将当前位置移到下页开头 012
\n :换行(LF) ,将当前位置移到下一行开头 010
\r :回车(CR) ,将当前位置移到本行开头 013
\t :水平制表(HT) (跳到下一个TAB位置) 009
\v :垂直制表(VT) 011

\\ 代表一个反斜线字符''\' 011
\’ 代表一个单引号(撇号)字符 092
\” 代表一个双引号字符 039
\? 代表一个问号 034
\0 空字符(NUL) 063
\ddd 1到3位八进制数所代表的任意字符 000
\xhh 十六进制所代表的任意字符 三位八进制

4.2 输入-存储

scanf:输入功能,可以从键盘输入数据给变量,使用scanf必须包含对应的头文件 #include<stdio.h>

格式:scanf("键盘输入匹配,格式化字符1,格式化字符2,",输入列表);

格式化字符:格式化字符位置匹配的内容输入到变量中

输入列表:列出要输入的变量

注意:如果是两个数值格式化字符,在键盘输入时需要用空格或回车隔开

5、C基础语法—运算符

只要是使用运算符进行运算,都会有结果,且结果就在运算的位置

5.1 算术运算符

+:加法

-:减法

*:乘法

/:除法

%:取余(模运算,整数)

进行运算时,如果是同种类型数据进行运算,则结果为对应的类型

5.1.1 隐式类型转换:

在进行各种运算操作,如果是不同的数据类型,会把不同的数据类型转换为相同的数据类型然后再进行运算(原则:精度低往精度高的类型转换),原数据不变

5.1.2 强制类型转换:

把数据的值取出,然后指定转换为某种类型,原数据不变

5.1.3 语法格式:

(要转换的类型)数据

5.2 关系运算符

(1)<:小于
(2)<=:小于等于
(3)>:大于
(4)>=:大于等于
(5)==:恒等于
(6)!=:不等于

关系运算符的作用是进行比较运算,判断关系是否成立(比较左右两边的表达式是否满足关系),比较的结果:成立时为真(值:1),不成立为假(值:0)

注意:

a - b > 精度  &&  a - b  < 精度

浮点数a 和 b 判断相等时(需在精度相同的情况下且数值相同才相等)

注意:

在进行运算时,如果有连续的多个运算符,则单一运算符进行运算之后得到结果才与下一个运算符进行运算

5.3 逻辑运算符

5.3.1 连接表达式

连接表达式,根据表达式的真假,进行组合得到新的结果,结果也是真(值:1)假(值:0)

逻辑运算符表示两个数据或表达式之间的逻辑关系,逻辑运算的结果也只有两个:真为1和假为0
(1)&& (与):

表达式1 && 表达式2

如果表达式1为真,且表达式2为真,逻辑与 结果 为真(值:1),否则 逻辑与 结果为假(只要有一个表达式为假,结果为假)(值:0)------判断,表达式1 和表达式2 是否同时成立为真

截断原则:当表达式1 已经为 假(0),不会运算 表达式2
(2)|| (或):

表达式1 || 表达式2

如果表达式1和表达式2 都为 假,逻辑或 结果为 假(值:0),否则 逻辑或为真(只有有一个表达式为真,结果为真)(值:1)-----判断,表达式1和表达式2 是否同时都不成立为假(是否存在表达式为真)

截断原则:当表达式1 已经为 真(1),不会运算 表达式2
(3)! (非):

!表达式

改变表达式的真假结果,如表达式为假,逻辑非 结果为 真(值:1),如表达式为真,逻辑非 结果为 假(值:0)

5.4 位运算符

位运算对数据中的对应的二进制位进行运算操作(不会涉及到符号位)

5.4.1 位运算

(1)&(位与)

表达式/数1 & 表达式/数2

把数1的二进制 与 数2的二进制,对应的每一位进行与运算操作(两个数对应的位有0,为0,都为1,则为1,位运算规则为:1 & 1 = 1       0 & 1 = 0       1 & 0 = 0      0 & 0 = 0)
(2)|(位或)

表达式/数1 | 表达式/数2

将两个运算量的各个相应位分别进行“或”运算操作(两个数对应的位,有1,为1,都为0,则为0,运算规则为:1 | 1 = 1       0 | 1 = 1       1 | 0 = 1       0 | 0 = 0) 
(3)^(位异或)

表达式/数1 ^ 表达式/数2

将两个运算量的各个相应位分别进行“异或”运算(两个数对应的位,相同为0,不同为1,运算规则为:1 ^ 1 = 0       0 ^ 1 = 1       1 ^ 0 = 1       0 ^ 0 = 0)
(4)~(位取反)

~数

将一个数据中所有位都取其相反值,即1变0,0变1,运算规则为:      ~1  -->  0         ~0   -->   1

5.4.2 移位运算

(1)<<(按位左移,低位自动补0,一共32位)

数据值 << 移动位数

将一个数据所有二进制位向左移若干位,左边(高位)移出的部分舍去,右边(低位)自动补零
(2)>>(按位右移,高位为1自动补1,高位为0自动补0,一共32位)

数据值 << 移动位数

将一个数据所有二进制位向右移若干位,右边(低位)移除的部分舍去,左边(高位)根据原最高位自动补值(原最高位为1:补1,元最高位为0,补0)

5.5 复合运算符

复合运算符:可以使用 = (赋值运算符)和 其他的运算符(算数运算符,位运算符)结合使用

+=、-=、*=、/=、%=、&=(与等于)、|=(或等于)、^=(异或等于)

变量  +=  表达式======> 变量 = 变量 + (表达式)

5.6 其他运算符

5.6.1 自增自减运算符

++ 、 –

变量++:先取变量的值,进行其他运算,然后变量 +1 ,使用变量时,使用+1之前的值

++变量:先把变量+1,然后取变量的值,进行其他运算

以下相同

变量 += 1;

变量–:

–变量:

前缀:先自增自减后再参与表达式运算。

后缀:先参与表达式运算,后自增自减。

5.6.2 条件运算符

三目运算符— ? :

条件表达式:表达式1 ? 表达式2 : 表达式3

表达式1为真,执行表达式2,把表达式2的结果作为整个条件表达式的结果

表达式1为假,执行表达式3,把表达式3的结果作为整个表达式的结果

如:

#include<stdio.h>
int main()
{
        int a=10,c;
        c = a>5 ? a++ : ++a;
        printf("a = %d,c = %d\n",a,c);
}

5.6.3 逗号运算符

表达式1,表达式2,…,表达式n

依次运算操作每个表达式,把最后一个表达式运算作为整个逗号运算符的结果

整个逗号表达式的值等于表达式n的值,也称逗号运算符为“顺序求值运算符”,比赋值运算符的优先级还低

如:

已知 a=2,b=4,c=6,求y

y = ((x1 = a + b)),(x2 = b + c),(x1 + x2);

5.6.4 sizeof运算符

sizeof(数值/类型):作用 计算数据 对应类型的大小,以字节表示

sizeof 运算符,计算类型、变量或表达式的空间大小(字节数)

sizeof(变量);

sizeof(表达式);

sizeof(类型);

5.6.5 运算符优先级(略)

作业:

(1)输入两个数求和

(2)提取电话号码 在下列输入字符串中豪华单间出租,联系电话:13888888888

(3)求下列表达式的值 int x=1,y=2,z=5;

x>0 && !(y3) || z>5 --> 1&&!(y3)|| z>5 --> 1&& 1|| z>5 -->1|| z>5 -->1

!(x+1>0) && y0 ||z>0 --> !(1) && y0|| z>0 -->0&& y==0 || z>0 --> 0 || z>0 --> 0||1–>1

x<0 || y0 && z>0 -->0|| y0 && z>0 --> 0&& z>0 -->0 &&0 -->0

x=y>z ? z>0? 5: y: 10; -->x=0 ? z>0? 5: y: 10; --> x=0? 1?5:y :10; --> x=0? 5 :10;–> x=10 //

运算嵌套采用就近原则

(4)使用三目运算符,求x,y,z中的最大值

思考:

(1)输入一个整数,输出其二进制

(2)输入一个数,分解质因数

(3)输入一个数,判断是否为质数 只能被1和它本身整除的数

(5)使用三目运算符,判断输入的年是否为闰年

六、选择—循环

6.1 if选择结构

根据实际的当前情况条件,选择性执行/选择性不执行某些功能内容

6.1.1 if-else选择结构

单分支选择结构

根据条件,如果满足条件 则 执行对应的功能操作代码,执行完后,然后继续往下执行;否则跳过对应的功能代码,继续往下执行

if(条件表达式)
{
语句块;
}
满足if选择的范围语句块,如果语句块只有 一条 语句,则{}可省略

条件表达式:只计算表达式的结果为 真(非0) 或 假(0)

如果满足条件则执行语句块,否则跳过语句块

双分支选择结构

满足条件表达式,执行一段语句功能内容,不满足则执行另一段功能内容;之后继续往下执行

if(表达式)
语句块1;
else
语句块2;

如果满足表达式,则执行语句块1,否则执行else 语句块2

多分支选择结构
if(表达式1)
语句块1;
else if(表达式2)
语句块2;
else if(表达式3)
语句块3;
……
[else
语句块n;]

多种情况选择性执行一种,判断第一种是否满足,满足则执行,不满足则判断下一种是否满足,满足则执行,不满足则继续判断…

注意:if选择,只看真假,经过各种运算得到 0 或者 非0 都可以

6.1.2 switch-case选择结构

switch选择结构,根据表达式的结果表示从多种情况进行选择,选择情况(表达式 == 情况)进行执行对应的语句块

switch (表达式)
{
case 常量表达式1:语句块1;break;//每个case 就是一个情况
case 常量表达式2:语句块2;break;
case 常量表达式n:语句块n;break;
default: 默认情况语句段n+1;[break];
}

注意:表达式和常量表达式 结果为 整型(因为要判断相等)

比较 switch 表达式   是否 等于  case 常量表达式 ,如果相等 则执行对应的语句块

default 表示 如果 switch 和case 比较所有都不相等,则执行default 默认语句块

当switch 表达式和 case 表达式 比较相等后则执行对应的语句块,同时所有的case 表达式都失效(则会从当前case 一直往后执行,直到swicth结束)

break:表示结束当前switch

6.2. 循环结构

重复多次执行某个功能

6.2.1 while循环

表达式为真,则执行一次要重复的内容(循环体语句),再次判断表达式是否真,表达式位置,则再次执行一次要重复的内容,继续判断表达式,直到表达式为假,则跳出循环执行while的后面内容

while (表达式)-------条件,是否重复执行
{
循环体语句;------要重复执行的内容
}

表达式的初始条件值

条件表达式

循环中包含改变条件值

作业:

1、企业根据营业额发奖金,低于10万,按0.1%发放,高于10万低于20万,10万按0.1%发放,高于10万间按0.2%发放;高于20万低于30万,10万按0.1%发放,10-20万按0.2%发放,高于20万部分按0.3%;高于30万,按0.4%发放,请输入金额,计算发放奖金

2、一个整数,它加上100是完全平方数,在加上100的基础上再加上168又是另一个完全平方数,求这个数

3、统计所有的水仙花数

4、有一对兔子,从第三个月开始每一个月都会生下一对兔子,小兔子经过三个月,每个月也能生下一对兔子,如果兔子不死,则,每个月有多少对兔子(只用输出前40个月,第一个月1对,第二个月1对)

5、猴子第一天摘了n个桃子,第一天吃了一半+1个,第二天又吃了剩下的桃子的一半+1,之后每天都是吃了前一天剩下的一半+1,第9天吃了后只剩下1个,问第一天摘了多少

6.2.2 do-while循环

do…while循环:先直接执行一次循环体,条件表达式从第二次开始判断是否满足,执行

语法结构:

do
{
循环体语句;
}
while (表达式);

while与do…while 区别:while从第一次条件开始判断,do…while 跳过第一次条件判断,从第二次判断开始;do…while最少执行一次

6.2.3 for循环

语法格式:

for (表达式1;表达式2;表达式3)
{
循环体语句;
}
表达式1:在整个for循环之前执行一次,且只执行一次,通常用于在for循环初始化条件的值(可以不进行设置,相当于没有初始化,可能在其他之前位置设置)

表达式2:循环条件,每次执行循环体前,先判断条件是否成立(判断一次,执行一次循环体)(可以不设置,相当于 条件一直为真 1)

表达式3:每次在执行一次循环体后,就立即执行(先于下次的条件判断),通常用于设置改变条件(可以不设置,相当于在表达式3中无操作)

表达式可以省略,但是 ; 必须添加

6.2.4 循环的嵌套

在循环内部循环体语句可能包含另一个循环,叫做循环的嵌套

while()
{
循环体
for()
{
}
}

外层循环执行一次,内层循环执行完一遍

6.2.5 break与continue

1、break

break:break语句作用是结束当前这个循环,跳出当前循环

while()
{
break;-------从当前位置结束整个循环
}

2、continue

continue:提前结束循环中的本次循环,跳过本次循环体没有执行完的内容,直接进行下一次

while循环使用continue直接结束本次循环体内容,直接进行下一次条件判断

for循环使用continue直接结束本次循环体内容,但是由于for循环在结束一次循环后,会执行表达式3,所以continue结束时,跳到表达式3执行,进行下一次条件判断

作业:
1、一辆汽车以平均80公里的时速行驶了4个小时。编写并运行一个C语言程序,显示这辆汽车已行驶的距离(公里),每半小时一次,直到旅程结束。
2、输入 年月日:如2021-7-5 ,计算当前日期是这一年的第几天
3、打印9 * 9 乘法表

七、函数

函数:就是一个独立的功能代码模块,在需要使用这个功能时,进行调用,就会去执行这个功能模块

库函数:由C语言标准实现的功能模块函数,编译器自带已经实现的函数

自定义函数:在程序中由于可能多次使用某个功能,自己实现这个功能模块函数,由用户对其进行定义,在其函数的定义中完成函数特定的功能,这样才能被其他函数调用

7.1 函数定义:

函数:包含两部分—函数头与函数体

函数头:对函数的描述说明,表示某个函数----标记

3个部分:

  • 返回值类型:函数功能结束,返回的结果是什么类型,表示有一个结果返回
  • 函数名:标识符,表示这个功能的名字,之后就使用这个名字来标识使用这个功能函数
  • 参数列表:在编写功能时不确定,需要在调用使用这个函数,传递的值
  • 函数体:功能模块的操作代码–功能的实现

定义:

返回值类型 函数名(参数列表)
{
函数体——函数实现特定功能的过程;
}

7.1.1 无参无返回值

void:空类型,没有数据类型
void 不能定义变量

void  函数名()
{
函数体;
}

7.1.2 无参有返回值

返回值数据类型  函数名()
{
函数体;
return 表达式值;
}

return:只要执行到return 语句,表示 函数功能到这里结束

return + 值:结束当前函数,同时把 值 返回,返回到调用位置(在调用位置得到函数的执行结果)

对于有返回值类型,在函数体中 必须包含 return + 值 语句

7.1.3 有参无返回值

函数名(参数的值1,参数值2,参数值3,…)
在调用时,参数值 需要和 函数定义的参数列表 一一对应

在调用时,会把参数值 赋值(传递)给 参数列表中的变量

注意:调用时,参数值 可能是变量,表示把变量的值传递给函数的参数列表,而不是把变量直接传递给参数列表

7.1.4 有参有返回值

函数名(参数值1,参数值2,参数值3,…)
调用有返回值函数,在调用位置就会得到函数返回结果

定义有参函数时,给定的参数列表,在参数列表中的参数,叫做 形式参数(形参)

调用有参函数时,给定的参数值,叫做实际参数(实参)

7.2 函数调用

在需要的位置使用这个函数功能,叫做函数调用

7.2.1无参无返回值调用

函数名()

调用无参函数,则没有参数列表,但小括号不能省略

7.2.2、无参有返回值调用

函数名()

调用有返回值函数,在调用位置就会得到函数返回结果

函数的嵌套调用
在调用一个函数的过程中,被调用的函数又可以调用另一个函数

函数的定义是平行的、独立的,不允许嵌套定义

7.3 函数的声明

编译时提示函数是什么样子的函数(有无函数,函数有无返回值,有无形式参数列表)

如果在前面调用了函数,在后面位置才进行定义需要在调用前进行声明

函数声明 语法:

返回类型 函数名(形式参数列表);

写法:

返回类型 函数名(参数类型1,参数类型2,参数类型3....);

返回类型 函数名(参数类型1  参数名1,参数类型2  参数名2,参数类型3 参数名3....);

7.3 递归函数

函数中直接或间接调用自己这个函数,叫做函数的递归调用,当前函数也叫做递归函数

通常递归函数需要用结束条件,在函数内部加控制语句,只有当满足一定条件时,递归终止

7.3.1 全局变量与局部变量

(1)局部变量

只要在函数内部定义的变量就叫做局部变量

函数的形式参数类似局部变量 ,与局部变量有相同的性质

性质:

生命周期:存储期限。变量的存储期限,在变量所在程序区块执行期间有效存储,区间结束或函数返回时,局部变量的值无法保留。

作用域:局部变量在定义所在的区域块内访问可达,离开区块不可访问。

程序块:用一对大括号{}括起来多条语句区域就是一个程序区块
(2)全局变量

不在函数内定义的变量叫做全局变量

性质:

生命周期:存储期限。变量的存储期限,在整个程序运行期间都存在有效。

作用域:从变量被定义的点开始一直到所在文件的末尾都可以使用访问。
(3)变量名的重名

在程序中,如果作用域相同则变量不能相同
在不同作用域时,允许定义相同的变量名,如果存在相同的变量则默认使用作用域小的变量进行操作

(4)变量的默认值

当变量定义时,如果没有进行初始化时,变量的默认值:

局部变量:随机值

全局变量:默认初始化为0
(5)static存储类型

static修饰局部变量:

延长生命周期为整个程序(程序结束变量的生命周期结束),但是作用域不变,只能在定义变量的作用域中使用(但作用域仍为局部)

当多次定义static 的局部变量时,只会定义第一次,之后都是跳过定义

static修饰全局变量:

设置为静态变量,只能在本文件内使用这个变量

static修饰的变量未初始化会自动初始化为0

练习:实现一个函数,计算指定范围内的质数

作业:

1、编写一个函数,输入多个字符,分别统计字母、空格、数字和其他字符的个数,打印分别的统计值

2、输入一个五位数,判断是否为回文数

3、实现函数输入x,y 打印 x和y 的公约数(公约数:就是都能整除的数,如 x = 9,y = 12,公约数为 3)

7.4 数组

数组:由多个数据组成一个数据集合,在集合中存在多个数据内容,数组是包含有多个数据值的数据结构,并且每个数据值具有相同的数据类型

数组元素:数组这个集合中的一个数据

7.4.1 一维数组

(1)一维数组的定义

定义:

类型 数组名[数组长度];

类型:每个数据的类型

数组名:整个数据集合的名字

数组长度:数据集合中数据的个数 

如:int a[4];

占用内存空间:类型 * 数组长度

以连续的内存空间创建数组,每个数组元素是相邻的

(2)一维数组元素的访问

存取特定的数组元素,通过数组名在后边加上一个用方括号表示整数值(整数值:数组取下标、索引:从0开始的编号位置)

格式:

数组名[下标]

下标:下标值只能是整数或结果为整数的表达式,取值范围是 0   ~   数组长度 - 1

注意:如果下标 >= 数组长度 叫做越界,不能使用
(3)一维数组的初始化

在定义一维数组时,可以对数组进行初始化,对数组进行初始化就是对数组的元素进行初始化
使用一个 {},在 花括号中,添加要对数组元素初始化的值

格式:

类型 数组名[元素个数] = {值1,值2,值3};

完全初始化:

类型  数组名[元素个数] = {值1,值2,值3 == 元素个数};

对数组中每个元素都进行初始化赋值,会按照值的顺序依次对数组元素进行初始化

float price[5] = {1,2,3,4,5};

部分初始化:

类型  数组名[元素个数] = {值1,值2,值3 < 元素个数};

按照顺序 依次初始化 数组中前几个值,未初始化 会有编译器初始化为0

float price[5] = {1,2,3}

指定初始化:

类型  数组名[元素个数] = {[下标] = 值1,[下标] = 值2,[下标] = 值3};

float price[5] = {[0] = 1,[4] = 2,[2] = 3};

在进行初始化时,由于会编写元素值,可以使用值的个数来表示元素个数,在定义的位置元素个数可以不写

类型 数组名[] = {值1,值2,值3};----虽然不写,但是有值的个数个元素

练习:在数组中输入10个数,找到数组中最大的元素以及存储的下标位置

7.4.2 二维数组

二维数组:一维数组的集合,集合中的数组元素是一维数组

例:二维数组有 5个一维数组元素,二维数组每个元素(一维数组)又包含8个数据

(1)二维数组的定义

定义:

数据类型 数组名[常量表达式1][常量表达式2];

数据类型:一维数组的元素数据类型

常量表达式1:二维数组的元素个数(有几个一维数组)

常量表达式2:在二维数组中的一维数组的元素个数(一维数组中有几个元素数据)

当定义了二维数组,在内存中存储二维数组,是按照行顺序,即先存储第一行(二维数组第一个一维数组),在存储第二行(二维数组第二个一维数组)

(2)二维数组的访问
数组名[二维数组下标]:二维数组中的某个一维数组

数组名[二维数组下标][一维数组下标]:二维数组中的一维数组的数据元素
(3)二维数组初始化

把二维数组按顺序,从第零个一维数组依次进行初始化

数据类型  数组名[常量表达式1][常量表达式2] = {值1,值2,值3,....};

int a[2][4] = {1,2,3,4,5,6};

把二维数组,每个{}表示初始一个一维数组

数据类型  数组名[常量表达式1][常量表达式2] = {{值1,值2},{值3,.}...};

int a[2][4] = {{1,2},{5,6,7}};

对于二维数组初始化时可以不指定一维数组的个数

即:

数据类型  数组名[][常量表达式2] = {};

int a[][3] = {1,2,3,4,5,6,7,8};-------有3个一维数组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值