一、C语言开发环境搭建
Linux系统作为学习C语言的开发环境
环境安装:
1、Ubuntu Linux.7z----------虚拟机系统
2、VMware:VMware Workstation 16 Pro 激活密钥.txt ; VMware-workstation-full-16.1.0
17198959.exe------虚拟机软件
3、安装VMware虚拟机.pdf----安装文档
1、安装虚拟机软件
2、在虚拟机软件中启用ubuntu系统
Ubuntu Linux.7z--解压
在vmware软件,打开虚拟机,选中
C语言环境:
ubuntu系统---->终端(terminal)
二、C语言基础
1.程序
程序:解决完成特定功能(任务)的流程步骤
计算机程序:让计算机去实现解决问题的步骤执行
计算机语言:计算机能够识别任务的内容(指令)
机器语言:使用0和1表示指令功能
汇编语言(助记符语言):把机器指令用助记符进行表示
高级语言:类似自然语言的编写方式
C语言:高级语言,适合嵌入式开发
2.C语言程序的编写编译
Linux中编写C语言程序
vim工具:在终端上编写文本文件内容——可以使用vim来写程序代码
vim:只是编辑器,类似于 windows 记事本,只负责写文本内容(程序内容)
vim终端的文本编辑器:创建、显示、编辑文本编辑器
vim操作:
vim:打开vim编辑
vim + xxxx文件名:使用vim 打开 xxxx文件
如果文件名不存在,创建一个新文件(临时)
vim操作文件,所有的操作都依靠键盘输入(键盘输入是:文本内容还是命令)
vim是多模式编辑器:
命令模式(默认):键盘输入(输入的任何内容),都是命令
插入模式:键盘输入,都是操作文本内容
底行模式:操作vim编辑器
第一个程序
C程序文件,都是以 .c作为结尾的:main.c 1.c sub.c test.c
#include <stdio.h>:stdio.h它是C语言的一个头文件,里面声明C的很多功能
#include 文件名,就是将文件中的内容,在当前 行#展开##.
C程序他有很多函数构成,函数是为了完成某个功能实现的.
最主要的 main,程序 从main函数开始执行.
编译: 将人类编程的程序,转换为机器可以认识的二进制程序.
gcc main.c 默认生成a.out 二进制文件
gcc main.c -o 二进制文件的名字: gcc main.c -o main.out
执行: ./main.out
3.关键字与标识符
1.关键字
关键字:在规范C语言时,用于表示一定的特殊含义的字符,只要在C程序中使用,就代表了一定
的操作和含义,约定的具有特定功能的单词或字符
int:整数类型
if:选择条件
for:循环
C语言程序中,我们所定义的名字不能和关键字重名(一样)
2.标识符
标识符:在当前程序中设定的一些字符符号表示,表示一定的意义,代表一个定义的作用(我们自
己所定义的字符符号含义),自己命名的符号
标识符的表示:
由字母数字和下划线构成,且只能以 字母或 下划线开始
A-Z , a-z , 0-9 , _
合法标识符:
abc,a1,a2,o_k
非法标识符:
%abc,a$b,1a
4.数据类型
在C语言程序中,数据值都有对应的数据类型
C语言是一种静态类型语言
基本类型:
1、整型:10、-10、1、-101
2、浮点型(实型):1.2、3.1415、-1.2
3、字符型:'a'、'#'、'0'
1.进制与转换
对于计算机而言,只认识 0 和 1
十进制表示:每位数据值范围:0、1、2、3、4、5、6、7、8、9 (满10进1)
120
二进制表示:每位数据值范围:0、1,计算机中存储数据以二进制存储 (满2进1)
0b110
八进制表示:每位数据值范围:0、1、2、3、4、5、6、7 (满8进1)
0110
十六进制表示:每位数据值范围:0、1、2、3、4、5、6、7、8、9、A(10)、B(11)、C(12)、D(13)、E(14)、F(15) (满16进1)
0x110
整数十进制转二进制:除以2取余数,把余数按照从低位到高位依次表示
15
/ 2-------------1
7
/ 2-------------1
3
/ 2-------------1
1
/ 2-------------1
0
15-------->(0000.....000) 1111
小数十进制转二进制:乘以2 取整 取到规定的位数
0.2====>
0.2
2
0.4-----------0
2
0.8-----------0
2
0.6-----------1
2
0.2-----------1
== 0011 0011 0011 ......
= 0011 0011 00
0.25====>
0.25
2
0.5-----------0
2
0.0-----------1
== 01
二进制转十进制:二进制每一位的权 乘以 当前位的值 (权:以2为底数,以位数为指数幂)的累加和
10101 ====>
1 * 2^0 + 0 * 2^1 + 1 * 2^2 + 0 * 2^3 + 1 * 2^4
= 1* 1 + 1 * 4 + 1 * 16 = 1 + 4 + 16 = 21
十六进制转十进制:十六进制每一位的权 乘以 当前位的值 (权:以16为底数,以位数为指数幂)的累加和
7A======>
A * 16^0 + 7 * 16^1 = 10 + 112 = 122
十进制转十六进制:除以16取余数,把余数按照从低位到高位依次表示
234
/ 16---------10(A)
14
/ 16--------14(E)
0
234=====>EA
二进制转十六进制/八进制:把四位/三位 二进制转为一个十六进制位/八进制位,如果高位不够补0进行转换
10101010111====>16进制
0 101 0101 0111===> 5 5 7
10101010111====>8进制
010 101 010 111====>2 5 2 7
十六进制/八进制转二进制:
2.数的存储
计算机以二进制方式(0、1)存储数据,但是数据中存在 正 负之分
有符号数:把数据中,最高位作为符号位,用0表示正数,用1表示负数
无符号数:数据中,所有位都是数据位,没有符号位,所有无符号数都是正数
计算机中存储数据是以 补码 格式存储
原码:数据的二进制格式
10:0 .....0000... 1010
-10:1 .....0000... 1010
反码:
正数:反码 == 原码
负数:在原码的基础上每一位(除了符号位)取反(1变为0,0变为1)
10:0 .....0000... 1010
-10:1 .....1111... 0101
补码:
正数:补码 == 原码
负数:在反码的基础上 + 1
10:0 .....0000... 1010
-10:1 .....1111... 0110
位:bit
一个单独的0或1 二进制----1bit
字节:byte
八位二进制---------1Byte 1B = 8bit
千字节:KByte---KB
一千个字节---------1KB 1KB = 1000B
3.基本数据类型
1.整型
整数存储
二进制,补码形式存储
整型:根据在计算机中设定的大小
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
2.浮点型(实型)
浮点型存储:
二进制,补码形式存储
数据部分 + 指数部分
浮点型:设定类型大小
float:单精度浮点型---32位(32bit),4B,精度:6/7
符号位:1bit
阶码:8bit
尾数:23bit
double:双精度浮点型-----64位(64bit),8B,精度:15/16
符号位:1bit
阶码:11bit
尾数:52bit
定义 一个32位浮点数:float
3.字符型
对于字符型数据,在计算机中存储,依旧使用二进制 0 和 1表示
对于每个字符统一用一种标准的二进制来表示
在C语言中,使用 ASCII码来表示(小整数)
ASCII码表
字符存储:
存储的字符对应的ASCII码,ASCII码就是整数,以二进制存储
字符类型:
char:字符类型--------8位(8bit),1B
字符类型可以当做整数进行操作:char 可以表示为 只有8位的整数
4.变量与常量
常量:在整个程序中都不会进行改变的数据
变量:在整个程序中可以进行变化的数据,在内存中存储数据后,空间中的数据值可以进行改变,变量在使用的使用需要有一个名字(能够找到对应的变量);变量是什么类型
对于变量而言,必须先有(定义),才能使用
变量定义:
存储类型 数据类型 变量名;
变量名:使用标识符来表示(相当于赋予了变量数据的含义)
存储类型:
auto:默认类型
通常可以省略,表示定义在栈区,由系统进行管理(编译器根据变量初始化表达式,推出变量类型)
static:静态类型
1.修饰局部变量:生命周期延长,作用域不变
2.修饰全局变量:只能在当前文件访问,不能跨文件访问
register:寄存器类型,存储到cpu中(通常等同于 auto)
extern:外部类型
变量初始化:
在定义变量时,为变量赋初始值
存储类型 数据类型 变量名 = 值;
5.输入输出
1.输出-打印
printf:由C语言标准所设计的输出功能,只要使用printf就可以实现输出打印(终端)
printf功能包含在 stdio.h中
所以要使用的话:#include<stdio.h>
格式:
printf("要输出打印的内容 格式化字符1,格式化字符2 ", 输出列表);
格式化字符:作用就是占位 表示要打印对应的数据值,以% 表示
输出列表:格式化字符要打印的数据
格式化字符:%
格式化字符输出指定的位数:
%m.p格式字符:m 数据的宽度,p小数的精度
在输出中,如果要输出某些特殊字符,在字符编码上没有对应的字符表示,在C语言中,设计转义字符:把普通字符转义为特殊字符,特殊字符转义为普通字符
转义字符: \
回车换行:\n
反斜线字符:\\
\:续行符
2.输入-存储
scanf:输入功能,可以从键盘输入数据给变量
使用scanf 必须包含对应的头文件 #include<stdio.h>
格式:
scanf("键盘输入匹配,格式化字符1,格式化字符2,",输入列表);
格式化字符:格式化字符位置匹配的内容输入到变量中
输入列表:列出要输入的变量
注意:如果是连续两个数值格式化字符,在键盘输入时需要隔开(空格、回车)
6.运算符
只要是使用运算符进行运算,都会有结果,且结果就在运算的位置
1.算数运算符
+:加法
-:减法
*:乘法
/:除法
%:取余数(求余运算只能用在整数)
进行运算时,如果是同种类型数据进行运算,则结果为对应的类型
隐式类型转换:C语言自动默认的转换
在进行各种运算操作,如果是不同的数据类型,会把不同的数据类型转换为相同的数据类型然后再进行运算(原则:精度低往精度高的类型转换),原数据不变
强制类型转换:人手工的转换
把数据的值取出,然后指定转换为某种类型,原数据不变
语法格式:
(要转换的类型)数据
练习:
工程今天生产了 5.9L 酸奶 , 6.8L果汁 , 3 L 咖啡 ,请问 今天一共生产了多少L ?
隐式类型转换: 5.9 + 6.8 + 3(隐式3.0) = 15.7L
强制类型转换: (int)5.9 + (int)6.8 + (int)3 = 5+6+3=14L
2.关系运算符
< 小于
<= 小于等于
> 大于
>= 大于等于
== 等于
!= 不等于
关系运算符是进行比较运算,判断关系是否成立(比较左右两边的表达式是否满足关系),比较结果:成立为真(值:1),不成立为假(值:0)
注意:在进行运算时,如果有连续的多个运算符,单一运算符进行运算之后得到结果再与下一个运算符进行运算
注意:
浮点数a 和 b 判断相等
a - b > -精度 && a - b < 精度
3.逻辑运算符
连接表达式,根据表达式的真 假,进行组合得到新的结果,结果也是 真(值:1) 假(值:0)
逻辑运算表示两个数据或表达式之间的逻辑关系,逻辑运算的结果也只有两个:真为1和假为0。
&& (与):
表达式1 && 表达式2
如果表达式1为真,且表达式2为真,逻辑与 结果 为真(值:1),否则 逻辑与 结果为假(只要有
一个表达式为假,结果为假)(值:0)------判断,表达式1 和表达式2 是否同时成立为真
截断原则:当表达式1 已经为 假(0),不会运算 表达式2
|| (或):
表达式1 || 表达式2
如果表达式1和表达式2 都为 假,逻辑或 结果为 假(值:0),否则 逻辑或为真(只有有一个表达式
为真,结果为真)(值:1)-----判断,表达式1和表达式2 是否同时都不成立为假(是否存在表达式为真)
截断原则:当表达式1 已经为 真(1),不会运算 表达式2
! (非):
!表达式
改变表达式的真假结果,如表达式为假,逻辑非 结果为 真(值:1),如表达式为真,逻辑非 结果为 假(值:0)
4.位运算符
位运算对数据中的对应的二进制位进行运算操作(不会涉及到符号位说法)
&(位与)
表达式/数1 & 表达式/数2
把数1的二进制 与 数2的二进制,对应的每一位进行与运算操作(两个数对应的位有0,为0,都为1,则为1,位运算规则为:1 & 1 = 1 0 & 1 = 0 1 & 0 = 0 0 & 0 = 0)
|(位或)
表达式/数1 | 表达式/数2
将两个运算量的各个相应位分别进行“或”运算操作(两个数对应的位,有1,为1,都为0,则为0,运算规则为:1 | 1 = 1 0 | 1 = 1 1 | 0 = 1 0 | 0 = 0)
^(位异或)
表达式/数1 ^ 表达式/数2
将两个运算量的各个相应位分别进行“异或”运算(两个数对应的位,相同为0,不同为1,运算规则为:1 ^ 1 = 0 0 ^ 1 = 1 1 ^ 0 = 1 0 ^ 0 = 0)
~(位取反)
~数
将一个数据中所有位都取其相反值,即1变0,0变1,运算规则为: ~1 --> 0 ~0 --> 1
<<(按位左移)
数据值 << 移动位数
将一个数据所有二进制位向左移若干位,左边(高位)移出的部分舍去,右边(低位)自动补零
>>(按位右移)
数据值 << 移动位数
将一个数据所有二进制位向右移若干位,右边(低位)移除的部分舍去,左边(高位)根据原最高位自动补值(原最高位为1:补1,元最高位为0,补0)
5.复合运算符
复合运算符:可以使用 = (赋值运算符)和 其他的运算符(算数运算符,位运算符)结合使用
+=、-=、*=、/=、%=、|= 、&=、^=
变量 += 表达式======> 变量 = 变量 + (表达式)
6.其他运算符
1.自增自减运算符
++ 、 --
变量++:先取变量的值,进行其他运算,然后变量 +1 ,使用变量时,使用+1之前的值
变量;
变量 += 1;
++变量:先把变量+1,然后取变量的值,进行其他运算
变量 += 1;
变量;
变量--
--变量
前缀:先自增自减后再参与表达式运算。
后缀:先参与表达式运算,后自增自减。
2.三目运算符
别称条件运算符/三元运算符
运算符---- ? :
条件表达式:
表达式1 ? 表达式2 : 表达式3
表达式1为真,执行表达式2,把表达式2的结果作为整个条件表达式的结果
为假,执行表达式3,把表达式3的结果作为整个表达式的结果
aa > bb ? (aa > cc ? aa : cc) : (bb > cc ? bb : cc);
3.逗号运算符
逗号运算符
表达式1,表达式2,…,表达式n
依次运算操作每个表达式,把最后一个表达式运算作为整个逗号运算符的结果
4.sizeof运算符
sizeof(数值/类型):作用 计算数据 对应类型的大小,以字节表示
sizeof 运算符,计算类型、变量或表达式的空间大小(字节数)
sizeof(变量);
sizeof(表达式);
sizeof(类型);
7、运算符优先级
7.选择结构
根据实际的当前情况条件,选择性执行/选择性不执行某些功能内容
1.if...else选择结构
1.单分支选择结构
根据条件,如果满足条件 则 执行对应的功能操作代码,执行完后,然后继续往下执行;否则跳过对应的功能代码,继续往下执行
if(条件表达式)
{
语句块;
}-----{}满足if选择的范围语句块,如果语句块只有 一条 语句,则{}可省略
条件表达式:只计算表达式的结果为 真(非0) 或 假(0)
如果满足条件则执行语句块,否则跳过语句块
2.双分支选择结构
满足条件表达式,执行一段语句功能内容,不满足则执行另一段功能内容;之后继续往下执行
if(表达式)
语句块1;
else
语句块2;
如果满足表达式,则执行语句块1,否则执行else 语句块2
3.多分支选择结构
if(表达式1)
语句块1;
else if(表达式2)
语句块2;
else if(表达式3)
语句块3;
……
[else
语句块n;]
if(chengji > 90){
printf(A);
}else if(cheng >70){
B
}else if(cheng >60){
C
}else {
D
}
上述内容,只会被执行 一个单元.
多种情况选择性执行一种,判断第一种是否满足,满足则执行,不满足则判断下一种是否满足,满足则执行,不满足则继续判断.....
注意:if选择,只看真假,经过各种运算得到 0 或者 非0 都可以
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
switch 和 if有什么区别:
switch 完成的功能相当于if
if(keynum=='A'){
}else if(keynum=='B'){
}...
即switch不支持 范围的运算,即 > <
8.循环结构
重复多次执行某个功能
1.while循环
表达式为真,则执行一次要重复的内容(循环体语句),再次判断表达式是否真,表达式位置,则再次执行一次要重复的内容,继续判断表达式,直到表达式为假,则跳出循环执行while的后面内容
while (表达式)-------条件,是否重复执行
{
循环体语句;------要重复执行的内容
}
表达式的初始条件值
条件表达式
循环中包含改变条件值
2.do...while循环
do...while循环:先直接执行一次循环体,条件表达式从第二次开始判断是否满足,执行
语法结构:
do
{
循环体语句;
}
while (表达式);
while与do...while 区别:while从第一次条件开始判断,do...while 跳过第一次条件判断,从第二次判断开始;do...while最少执行一次
3.for循环
语法格式:
for (表达式1;表达式2;表达式3)
{
循环体语句;
}
表达式1:在整个for循环之前执行一次,且只执行一次,通常用于在for循环初始化条件的值(可以
不进行设置,相当于没有初始化,可能在其他之前位置设置)
表达式2:循环条件,每次执行循环体前,先判断条件是否成立(判断一次,执行一次循环体)(可
以不设置,相当于 条件一直为真 1)
表达式3:每次在执行一次循环体后,就立即执行(先于下次的条件判断),通常用于设置改变条件
(可以不设置,相当于在表达式3中无操作)
表达式可以省略,但是 ; 必须添加
4.循环的嵌套
在循环内部循环体语句可能包含另一个循环,叫做循环的嵌套
while()
{
循环体
for()
{
}
}
外层循环执行一次,内层循环执行完一遍
1.break
break:break语句作用是结束当前这个循环,跳出当前循环
while()
{
break;-------从当前位置结束整个循环
}
2.continue
continue:提前结束循环中的本次循环,跳过本次循环体没有执行完的内容,直接进行下一次
while循环使用continue直接结束本次循环体内容,直接进行下一次条件判断
for循环使用continue直接结束本次循环体内容,但是由于for循环在结束一次循环后,会执行表达式3,所以continue结束时,跳到表达式3执行,进行下一次条件判断
9.函数
函数:代码或代码块的集合,或特定功能代码的集合,把实现某种功能的代码单独实现形成一个整
体,可以进行单独使用。就是一个独立的功能代码模块,在需要使用这个功能时,进行调用,就会
去执行这个功能模块
库函数:由C语言标准实现的功能模块函数,编译器自带已经实现的函数
自定义函数:在程序中由于可能多次使用某个功能,自己实现这个功能模块函数,由用户对其进行
定义,在其函数的定义中完成函数特定的功能,这样才能被其他函数调用
1.函数定义
函数:包含两部分---函数头与函数体
函数头:
对函数的描述说明,表示某个函数----标记
3个部分:
返回值类型:函数功能结束,返回的结果是什么类型,表示有一个结果返回
函数名:标识符,表示这个功能的名字,之后就使用这个名字来标识使用这个功能函数
参数列表:在编写功能时不确定,需要在调用使用这个函数,传递的值
函数体:
功能模块的操作代码--功能的实现
定义:
返回值类型 函数名(参数列表)
{
函数体——函数实现特定功能的过程;
}
函数定义的四种格式:
1、无参无返回值
void:空类型,没有数据类型
void 不能定义变量
void 函数名()
{
函数体;
[return;]
}
没有返回值可以使用void修饰返回值类型
2、无参有返回值
返回值数据类型 函数名()
{
函数体;
return 表达式值;
}
有返回值在定义函数时就要给定返回值类型 如int float char
return:只要执行到return 语句,表示 函数功能到这里结束
return + 值:结束当前函数,同时把 值 返回,返回到调用位置(在调用位置得到函数的执行结果)
对于有返回值类型,在函数体中 必须包含 return + 值 语句
3、有参无返回值
void 函数名(参数列表):使用参数列表作为函数功能的输入,在编写函数功能时,存在不确定的一些数据值,使用参数列表来表示在定义函数功能时不确定;在使用时,根据参数列表情况,调用时传递参数列表实际的值
{
函数体;
}
参数列表格式:
数据类型1 变量名1,数据类型 变量名2,......
4、有参有返回值
返回值类型 函数名(参数类型1 参数名1,参数类型2 参数名2,...)
{
函数体;
return 值;
}
2.函数调用
在需要的位置使用这个函数功能,叫做函数调用,即:运行一次这段代码块
调用过程:
当调用时,跳转到对应函数位置进行执行函数功能,当函数执行完({}结束或return语句), 再跳转回调用位置,继续执行
1、无参无返回值调用
函数名()
调用无参函数,则没有参数列表,但小括号不能省略
2、无参有返回值调用
函数名()
调用有返回值函数,在调用位置就会得到函数返回结果
3、有参无返回值调用
函数名(参数的值1,参数值2,参数值3,......)
在调用时,参数值 需要和 函数定义的参数列表 一一对应
在调用时,会把参数值 赋值(传递)给 参数列表中的变量
注意:调用时,参数值 可能是变量,表示把变量的值传递给函数的参数列表,而不是把变量直接传递给参数列表
4、有参有返回值调用
函数名(参数值1,参数值2,参数值3,.....)
调用有返回值函数,在调用位置就会得到函数返回结果
定义有参函数时,给定的参数列表,在参数列表中的参数,叫做 形式参数(形参)
调用有参函数时,给定的参数值,叫做实际参数(实参)
3.函数的嵌套调用
在调用一个函数的过程中,被调用的函数又可以调用另一个函数
函数的定义是平行的、独立的,不允许嵌套定义
4.函数的声明
编译时提示函数是什么样子的函数(有无函数,函数有无返回值,有无形式参数列表)
如果在前面调用了函数,在后面位置才进行定义需要在调用前进行声明
函数声明 语法:
返回类型 函数名(形式参数列表);
写法:
返回类型 函数名(参数类型1,参数类型2,参数类型3....);
返回类型 函数名(参数类型1 参数名1,参数类型2 参数名2,参数类型3 参数名3....);
5.递归函数
函数中直接或间接调用自己这个函数,叫做函数的递归调用,当前函数也叫做递归函数
通常递归函数需要用结束条件,在函数内部加控制语句,只有当满足一定条件时,递归终止
10.全局变量与局部变量
1.局部变量
只要在函数内部定义的变量就叫做局部变量
函数的形式参数类似局部变量 ,与局部变量有相同的性质
性质:
生命周期:存储期限。变量的存储期限,在变量所在程序区块执行期间有效存储,区间结束或函数返回时,局部变量的值无法保留。
作用域:局部变量在定义所在的区域块内访问可达,离开区块不可访问。
程序块:用一对大括号{}括起来多条语句区域就是一个程序区块
2.全局变量
不在函数内定义的变量叫做全局变量
性质:
生命周期:存储期限。变量的存储期限,在整个程序运行期间都存在有效。
作用域:从变量被定义的点开始一直到所在文件的末尾都可以使用访问。
3.变量名的重名
在程序中,如果作用域相同则变量不能相同
在不同作用域时,允许定义相同的变量名,如果存在相同的变量则默认使用作用域小的变量进行操作
4.变量的默认值
当变量定义时,如果没有进行初始化时,变量的默认值:
局部变量:随机值
全局变量:默认初始化为0
5.static存储类型
static静态存储类型
static修饰局部变量:
延长生命周期为整个程序(程序结束变量的生命周期结束),但是作用域不变,只能在定义变量的作用域中使用(但作用域仍为局部)
当多次定义static 的局部变量时,只会定义第一次,之后都是跳过定义
static修饰全局变量:
设置为静态变量,只能在本文件内使用这个变量
static修饰的变量未初始化会自动初始化为0
11.数组
数组:由多个数据组成一个数据集合,在集合中存在多个数据内容,数组是包含有多个数据值的数据结构,并且每个数据值具有相同的数据类型
数组元素:数组这个集合中的一个数据
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个数,找到数组中最大的元素以及存储的下标位置
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个一维数组