学习目标:10天学会c语言基础
一.学习内容:
1.数据
2.数据的输入和输出
3.运算符和表达式
4.程序的结构和控制语句
5.数组
6.指针
7.函数
二.学习内容
数据
1.计算机的数据表示(进制转换)
分为:数值数据、非数值数据
2.非数值数据(不能够直接进行算数运算的数据)
字符、图片、声音
‘a’ ‘b’
ASCII码表(可百度高清图片):规定了每一个字符以哪八位二进制数表示(1字节 == 8bir)
3.数值数据(可以直接进行算术运算的数据)
十进制、二进制、八进制、十六进制
十进制:逢十进1: 0~9构成
二进制:逢二进1: 0~1构成
八进制:逢八进1: 0~7构成
十六进制:逢十六进1: 0~9,a~f构成
为了区分不同的进制:我们给八进制前加0,十六进制前加0x(0X)
76(十进制) 076(八进制) 0x76(0X76)(十六进制)
(如果A-F是大写,X就要用写)
4.基本数据类型
关键字:系统预先定义好的,有特殊含义的,并且都是小写,不能重复定义(32个)
数据类型:char、short、int、long、float、double、struct、enum、union、void
控制语句:if、else、switch、case、default、for 、do、while、break、continue、goto
存储类型:auto、static、extern、register
const:只读
return:返回函数
signed:有符号数
unsigned:无符号数
sizeof:计算所占内存空间的大小:单位(字节) sizeof(数据类型)//sizeof(变量名)
typedef:给已有的数据类型起别名;
volatile:防止编译器优化
标识符:程序员自己定义的,一般用来定义变量名,函数名,类型名
- 由数字、字母、下划线构成
- 第一个不能为数字
- 不能和关键字重名(建议见名知意!!!)
基本数据类型所占字节长度:
字符型: char --- 1字节
整型: short-----2字节 int------4字节 long--- 32位操作系统:4字节/64位操作系统:8字节
浮点型:float-----4字节 double---8字节
有符号数和无符号数:
Signed:有符号数
有符号数:有正数有负数
最高位用来表示符号位,0正1负
在计算机中:数据是以二进制的补码的形式存储的
正数:正数的原码,反码,补码都是一样的
负数:
原码:最高位为符号位,其他位为数据位(直接转为二进制)
反码:原码的符号位不变,其他位取反(0变1,1变0)
1.字符型数据
Char-----------1字节 == 8 bit
值域范围:
Unsigned char :0000 0000-----------1111 1111------(0~255)
Signed char :1000 0000------------0111 1111-----(-128~127)
2.整型数据
值域范围:
Int整型:== 4字节== 32bit
Unsigned int:(0 ~ 2^32-1)
0000 0000 0000 0000 0000 0000 0000 0000--1111 1111 1111 1111 1111 1111 1111 1111
Signed int:(-2^31 ~ 2^31-1 )
1000 0000 0000 0000 0000 0000 0000 0000--0111 1111 1111 1111 1111 1111 1111 1111
Short:== 2字节== 16bit
Unsigned short:(0 ~ 2^16-1)
0000 0000 0000 0000--------------1111 1111 1111 1111
Signed short:(-2^15~ 2^15-1)(-32768~32767)
3.浮点型数据
浮点型的存储方式决定了他不能够准确的表示一个数,只能近似的表示一个数
单精度浮点数:
float(4字节)---------保证6~7位有效数据(%f)(默认输出小数点后6位)
双精度浮点数:
double(8字节)-------保证15~16位有效数据(%lf)(默认输出小数点后6位)
%.nf-----------保留小数点后n位进行输出
5.常量
程序运行期间,不能也不会被改变的量
1 字符常量
‘a’ ‘A’
2 整型常量
二进制:1010
八进制:066
十六进制:0xaf5
十进制:99,-2
注意:默认情况下,整形常量为有符号数;
无符号的int类型:98U
Long类型:76L
无符号的长整型:78UL
3 浮点型常量
小数:3.14 0.00001 10000(浮点型常量包含整形常量)
指数:1e+5 == 100000 1e-5 == 0.00001
%g: 选择小数或者指数中比较合适(比较短)的一种情况进行输出
4 字符串常量
“hello”占几个字节
‘h’‘e’‘l’‘l’‘o’‘\0’
(字符串用双引号括起来,字符用单引号括起来)
注意:字符串由‘\0’结尾
5 标识常量(宏)
宏只是一个单纯的替换!
#define 宏名 表达式
注意:1、宏名一般用大写,为了和普通的变量区分开来吗,当然小写也可以
2、宏后没有分号
宏函数:
既有宏的特点,又有函数的特点
#define 函数名(形参列表) 函数体
注意:宏只是一个单纯的替换,他不会考虑运算符优先级的问题,因此,需要给每个形参,以及整个表达式都加上括号!
5.变量
1.变量的存储空间
2.定义变量
存储类型 数据类型 变量名;
//存储类型:决定了在哪块区域去开辟空间
//数据类型:决定了开辟的内存空间的大小
//变量名:开辟的内存空间的名字
存储类型:auto、static、extern、register
3.局部变量和全局变量
局部变量
定义在函数(任何)体内的变量
全局变量
定义在函数(任何)体外的变量
4.存储类型
auto、static、extern、register
Auto:修饰的变量存储在栈区,只能修饰局部变量
Static:修饰的变量存储在静态区,即可以修饰全局变量,也可以修饰局部变量,用static修饰的变量叫做静态变量
extern:修饰的变量存储在静态区,只能修饰全局变量
register:修饰的变量存储在寄存器中,只能修饰局部变量
5.初始化
全局变量如果没有初始化,他的值为0!
局部变量如果没有初始化,他的值为随机值!(为了避免随机值,我们一般给局部变量初始化为0!)
Static: 即可以修饰局部变量,也可以修饰全局变量,存储在静态区
- 如果static修饰局部变量:
作用:延长局部变量的生命周期;如果局部变量没有初始化,那么局部变量的值为0;如果初始化了,只能初始化1次
2.如果static修饰局部变量:
作用:限制作用域,只能在本.c文件内使用
6.生命周期和作用域
生命周期
从开辟空间到空间释放
作用域:
局部变量:
生命周期:从定义开始,到模块(距离他最近的大括号)结束;
作用域:大括号内(距离他最近的大括号)
用static修饰的局部变量:
生命周期:从定义开始,到程序结束
作用域:大括号内(距离他最近的大括号)
全局变量:
生命周期:从定义开始,到程序结束
作用域:整个程序
用static修饰的全局变量:
生命周期:从定义开始,到程序结束
作用域:本文件内(本个.c内)
7.数据类型转换
强制转换数据类型(我们自己去转换的):
隐式转换数据类型(编译器帮我们转换的):
横向箭头:不管有没有进行混合运算,都会进行转化!
char、short使用的时候按照:int去用
注意:float在使用的时候按照:double去用
纵向箭头:只有在进行混合运算的时候,才会进行转换!
数据的输入和输出
1.输入输出概念
函数:具有独立功能的模块
标准输入输出函数:scanf、printf(对变量的类型没有限制)
输入:从键盘拷贝数据到内存中
输出:将内存中的数据拷贝到终端
2.输出方式
printf(“格式控制串”,输出表);
格式控制串:原样输出的内容 + 格式化符
输出表:输出的内容
注意:输出的内容要和格式化符一一对应!!!
整型:
%d:十进制的整数
%o:八进制
%x %X:十六进制
#:自动在八进制和十六进制前加上前缀
%u:以无符号的整型
%hd:short类型
%ld:long类型
字符型:
%c:字符型
浮点型:
%f:float类型
%lf:double类型
%g:选择小数和指数中比较合适的一种情况进行输出
%e:指数形式
%m.nf:
.nf:保留小数点后n为进行输出
m:指定我们输出的域宽,默认(m>0)右对齐,m的值大于数据的实际长度时,左边补空格,m的值小于数据的实际长度时,原样输出!(反之:m<0----左对齐:右边补空格)
3.输入方式
scanf(“格式控制串”,地址表);
格式控制串:原样输入的内容+格式化符
地址表:&+变量名(你要给哪片空间去输入)
注意:
- scanf的格式控制串中,不要去加多余的修饰语,如果要加,原样输入
- 如果输入“%d%d”时要给多个变量进行赋值,在格式控制串之间没有多余的修饰语时,以空格,回车,tab作为第一个变量输入结束的标志
- 全部输入结束后,必须以回车作为结束符
- 如果是“%c%c”时,在输入时,不能有空格回车tab键,因为空格回车tab也是字符
4.字符的输入输出函数
字符的输入函数:
Int getchar();
//返回值:输入的字符的ascii码值
字符的输出函数:
putchar(int);
//参数:要输出的字符的ascii码值
运算符和表达式
单算移关与,异或逻条赋
单目运算符,算术运算符,左移右移,关系运算符、按位与、异或 、按位或、逻辑运算符、条件运算符、赋值
1.算术运算符
+、-、*、/、++、--、%
注意:%不能用于浮点数
++在前:先自加,在赋值
++在后:先赋值,在自加
注意:如果++a和a++单独成立一条语句,那么都相当于给a+1
2.关系运算符
> < >= <= == !=
3.逻辑运算符
&&、 || 、 !
&&:
表达式1 && 表达式2
截断法则:有一个为假,结果就为假,前一个为假,后面就不在进行运算了
||:
表达式1 || 表达式2
截断法则:有一个为真,结果就为真,前一个为真,后面就不在进行运算了
4.sizeof运算符
Sizeof(数据类型)/ sizeof(变量名)
5.三目运算符
表达式1 ? 表达式2 :表达式3
先去判断表达式1是否成立,如果成立,就将表达式2的值作为整个表达式的值,如果表达式1不成立,则将表达式3的值作为整个表达式的值
6.逗号运算符
表达式1,表达式2,表达式3,表达式4,.........,表达式n
从左往右依次去计算每个表达式的值,最后,将表达式n的值作为整个表达式的值
注意:逗号运算符的优先级是最低的,因此在使用的时候加上括号!!
7.位运算符
& 、 | 、 ~ 、 ^、 << 、 >>
7.1.与运算(&)
&:都为1,才为1(有一个0,就为0)
1001 0101
& 0100 1111
0000 0101
案例:将1101 0011 的0~2位清零
1101 0011
& (1111 1000)------------&(~7)---------~(111)------(111-----111000)
1101 0000
一般用&:给某些位置零
7.2 或运算(|)
|:都为0,才为0(有一个1,就为1)
1101 0100
| 0010 1111
1111 1111
案例:将1101 0010的0~2位置为101
- 清零: &(~7)---------- -------------------1101 0 000
- 置位: |(000---- 101)----|(5)-----1101 0 101
7.3 取反(~)
0变1, 1变0
~(1001 0110) == 0110 1001
7.4 异或(^)
相同为0,不同为1
1101 0010
^ 0111 0110
1010 0100
7.5 左移(<<)
无符号数:高位丢弃,低位补0
0000 0001 << 2
0000 0100 -------- 4
有符号数:
正数:符号位不变,高位丢弃,低位补0
0000 0001 <<2
0 000 0100----- +4
负数:符号位不变,高位丢弃,低位补0
-4 << 2
原码:1 000 0100
反码:1 111 1011
补码:1 111 1100
左移:1 111 0000
原码:1 000 1111+1------------1001 0000----- -16
7.6右移(>>)
无符号数:低位丢弃,高位补0
0000 0100
0000 0001 ------- 1
有符号数:
正数:符号位不变,低位丢弃,高位补0
4: 0000 0100
0000 0001---------- 1
负数:符号位不变,低位丢弃,高位补1
-1:
原码:1000 0001
反码:1111 1110
补码:1111 1111
补码:1111 1111
反码:1000 0000
原码:1000 0001------------(-1)
总结:
左移:
无符号数:高位丢弃,低位补0
有符号数:符号位不变,高位丢弃,低位补0
右移:
无符号数:低位丢弃,高位补0
有符号数:符号位不变,低位丢弃,高位补符号位
程序的结构和控制语句
1.程序的结构
一个基本的C语言程序通常包括以下部分:
-
预处理指令:在代码实际编译之前进行预处理,包括引入头文件和宏定义等。
#include <stdio.h>
#define MAX_VALUE 100
-
主函数(main函数):C程序的执行从
main
函数开始。main
函数是程序的入口,从这里开始执行代码。int main() { // 代码逻辑 return 0; }
-
变量声明:在
main
函数之前,可以声明全局变量。int globalVar = 10;
-
函数定义:除了
main
函数外,你可以自定义其他函数来实现特定的任务。int add(int a, int b) { return a + b; }
2.三大结构
2.1顺序结构
语句按照一定的先后顺序去执行
2.2选择结构
2.2.1单分支选择结构
if(表达式)
{
语句;
}
先判断表达式是否成立,如果成立,执行语句
2.2.2 双分支选择结构
if(表达式)
{
语句1;
}
else
{
语句2;
}
先判断表达式是否成立,如果成立,就执行语句1,否则,执行语句2;
2.2.3 多分支if选择结构
If(表达式1)
{
语句1;
}
else if(表达式2)
{
语句2;
}
Else if(表达式3)
{
语句3;
}
。。。
Else if(表达式n-1)
{
语句n-1;
}
Else
{
语句n;
}
从上往下,依次去判断每个表达式是否成立,如果成立,就执行对应的语句
2.2.4 switch语句
Switch(表达式)
{
Case 标号1:
语句1;
Case 标号2:
语句2;
Case 标号3:
语句4;
。。。。
Case 标号n-1:
语句n-1;
Default:
语句n;
}
注意:
- 表达式不能为float类型;
- 标号必须为常量;
- 当表达式等于标号的时候:执行冒号后面的语句!(如果都不相等,默认执行default后面的语句!)直到switch,case语句结束,或者遇到break语句结束!
结束条件:(停止输出冒号后面的语句的条件)
- 遇到break,跳出switch语句
- Switch,case语句结束
2.3循环结构
重复的去做一件事
三要素:循环的起始条件、循环的终止条件、循环变量的变化
2.3.1 for循环
for(表达式1 ;表达式2 ;表达式3)
{
//循环体;
}
表达式1:循环的起始条件
表达式2:循环的终止条件
表达式3:循环变量的变化
先执行表达式1;然后判断表达式2是否为真,如果为真,则执行循环体,然后执行表达式3,以此反复,直至表达式2为假,跳出循环!
2.3.2 while语句
While(表达式)
{
循环体;
}
判断表达式是否成立,如果成立,则执行循环体,否则,跳出循环
2.3.3 do...while语句
do
{
//循环体
}while(表达式);
先执行循环体;判断表达式是否成立,如果成立,则执行循环体,否则,跳出循环;
总结:区别
while语句:先判断,在执行,语句至少执行0次;
do...while语句:先执行,在判断,语句至少执行1次;
2.3.4 break和continue的区别:
break:1.跳出switch、case语句
2.跳出循环
continue:跳出本次循环,进入下一次循环
2.3.5 goto语句
无条件跳转语句
一般格式为:
goto 标号;
标号:
数组
1.一维数组概念
一组数据类型相同的元素组成的集合(一堆数据类型相同的数据组合在一起!)
特点:1、数据类型相同 2、地址连续(打印地址:%p)
2.
2.定义
存储类型 数据类型 变量名;
Int a;
存储类型:auto、static、register、extern
Auto:局部:栈区
Static:全局和局部:静态区
作用:全局:限制作用域,只能在本文件内使用
局部:延长局部变量的生命周期,如果没有初始化,则局部变量的值== 0,初始化:只能初始化一次
Extern:全局:静态区
作用:告诉编译器,该变量已经在其他文件中定义过了
Register:局部
存储类型 数据类型 数组名[元素的个数];
Int a[5];
//相当于定义了一个数组:数组名为:a:数组中有5个元素,这五个元素都是int类型的
数据类型:数组中元素的数据类型
数组的数据类型:int [5]
数据类型:去掉变量名,剩下的就是数据类型!
开辟的内存空间的大小= sizeof(数据类型)*元素的个数
数组名:数组名代表的是数组首元素的地址!(表示整个数组)
3.初始化
3.1 部分初始化
在进行部分初始化时,未初始化的部分其值为0;因此,利用部分初始化的特点:给数组进行清零!
数组清零: int arr[100] = {0};
3.2 全部初始化
Int a[5] = {1,2,3,4,5};
Int a[ ] = {1,2,3};//在进行全部初始化时,数组元素的个数是可以省略的,有后面赋值的具体的元素个数来决定!
总结:
1、数组定义在函数体内时,如果没有初始化,(相当于局部变量),数组中的值为随机值
2、数组定义在函数体外,如果没有初始化,(相当于全局变量),数组中的值为0
3、数组定义在函数体内,用static修饰(相当于用static修饰的局部变量)数组中的值为
4.访问
数组名[下标]
注意:下标从0开始
5.冒泡排序
思想:从左往右,两两依次比较,如果前一个数比后一个数大,就交换位置,反之,不变!
6.字符数组
整型数组:保存一组int类型的数据
存储类型 数据类型 数组名[元素的个数];
数据类型:数组中元素的数据类型
Int arr[5];
字符数组:保存一组char类型的数据
存储类型 数据类型 数组名[元素的个数];
数据类型:数组中元素的数据类型
定义: char str[10];//定义了一个字符数组str,该数组中可以存放10个char类型的字符
数组所占的内存空间== sizeof(char)*10 = 10
数组的数据类型:char [10];//去掉数组名
字符数组的本质就是字符串;
7.字符串的输入输出函数
7.1字符串的输出函数
%s:字符串
Printf(“ %s ”, str);
puts(数组名);
功能:将数组中的内容打印到终端,并且自动换行
注意:打印到‘\0结束
7.2 字符串的输入函数
Scanf(“%s”,str);
gets(数组名);
功能:将输入的字符串保存在数组中,并且在末尾自动添加‘\0’
注意:gets不会进行越界检查,如果超出范围,就会操作未申请到的内存空间,段错误
出现段错误的原因:非法操作你没有申请的空间。
7.3 总结:
7.3.1 scanf和gets的区别
gets是以回车作为结束符,而scanf以空格,回车,tab作为结束符
缓冲区:
gets:当完成字符串的输入之后,会自动清空缓冲区的内容
scanf:当完成字符串的输入之后,会在缓冲区遗留空格、回车、tab
注意:
gets:首先检查缓冲区里面是否有内容,如果有,直接拿来用,否则等待输入
scanf:标准输入函数:每一次只能等待键入
7.3.2 printf和puts的区别
Puts后会自动添加换行,而printf不会!
8.二维数组
8.1 概念(数组数组)
整形数组: 一堆int类型组成的集合
字符数组: 一堆char类型组成的集合
浮点型数组: 一堆float类型组成的集合
数组数组: 一堆数组类型组成的集合
二维数组:元素为一维数组的一维数组
一组数组类型的元素组成的集合(一堆一维数组组成的数组)
元素:一维数组(元素:一维数组的里面存放的元素的个数以及数据类型必须相同)
- 数据类型相同 2、地址连续
- 定义
定义一个:一维整型数组:
存储类型 数据类型 数组名[元素的个数];
Int a[3];
//一维数组中有3个int类型的元素
数组的数据类型:int [3];
定义一个:二维数组:
存储类型 数据类型 数组名[元素的个数][一维数组中元素的个数];
存储类型 数据类型 数组名[行数][列数];
//将2个一维数组(int [3])组合在一起
Int arr[2][3];
//数据类型:一维数组中元素的数据类型
行数:二维数组元素的个数:一维数组的个数
列数:一维数组中元素的个数
二维数组中真正的元素的个数 == 行数*列数
8.2 二维字符数组
一维字符数组:
存储类型 数据类型 数组名[元素的个数];
Char str[10] = “hello”;
//定义了一个一维字符数组str,该数组由10个char类型的元素组成
一维字符数组的本质-----字符串!
一维字符数组的数据类型:char [10];
Scanf(“%s”,str);
Printf(“%s”,str);
二维字符数组:
存储类型 数据类型 数组名[行数][列数];
Char str[5][10];
行数:一维字符数组的个数==========字符串的个数
列数:每个一维数组中元素的个数====每个字符串长度
//定义了一个二维字符数组str
该二维字符数组中有5个字符串,每个字符串的长度为10字节
6.指针
6.1 什么是指针?
Char是一种数据类型,它是一种保存字符的数据类型(‘a’,‘b’)
Int 是一种数据类型,它是一种保存整形数的数据类型(10,20)
float是一种数据类型,他是一种保存浮点数的数据类型(3.14 2.37)
指针是一种数据类型,它是一种保存地址的数据类型(%p打印出来的地址编号)
6.2 什么是地址?
内存分配的最小单元是字节,每一个字节都有一个编号,这个编号就叫做地址!
地址的本质:内存单元的编号!
指针:
指针:指针就是地址
指针的本质:内存单元的编号
6.3 指针常量
Char定义的变量-----------保存字符常量
Int定义的变量----------保存整形常量
float定义的变量-------保存浮点型常量
指针定义的变量-------保存指针常量(地址:专门用来保存内存单元的编号)
6.4 指针变量
如何定义一个指针变量?
存储类型 数据类型* 变量名;
Int * p;
//*用来表示p是一个指针变量
//定义了一个指针变量p,这个p用来保存类型变量的地址
//指针保存谁的地址========等价于===========指针指向谁
数据类型:指针指向的数据类型
指针p的数据类型:int *;
指针指向的数据类型:去掉一个*,在去掉变量名,剩下的就是指针指向的数据类型!
注意:*和&互为逆运算
6.5 指针的赋值
指针的赋值:相当于改变指针的指向;
注意:对指针变量进行赋值时,要注意类型匹配!
注意:
在32os中:所有的指针都占4字节
在64os中,所有的指针都占8字节
6.6 空指针
没有指向的指针:NULL(值为0的指针,就认为该指针没有指向)
注意:0号地址禁止操作
6.7 野指针
不知道指向哪里的指针
局部变量:没有初始化:随机值
局部指针:没有初始化:野指针
6.8二级指针
定义一个整形变量;
存储类型 数据类型 变量名;
Int a = 10;
//编译器开辟4个字节的内存空间:这片空间的名字叫a,这片空间中保存的是整形数
a的数据类型:int
定义一个一级整形指针
存储类型 数据类型 * 指针变量名;
Int * p = &a;
//编译器开辟4字节的内存空间:这片空间的名字叫p,这片空间中保存的是整形数的地址
p的数据类型:int *
定义一个二级整形指针
存储类型 数据类型 * 指针变量名;
Int* * pp = &p;
pp的数据类型:int**;
Int *:pp指向的数据类型========等价于====pp保存什么数据类型变量的地址
指针指向谁=========等价于============指针保存谁的地址
6.9总结
- 指针的数据类型:去掉变量名,剩下的就是数据类型
Int *p;//int *
Int **p;//int **
Int ***p;//int ***
- 指针指向的数据类型:去掉变量名和一个*,剩下的就是指针指向的数据类型
Int *p;//指向的数据类型:int
Int **p;//指向的数据类型:int *
Int ***p;//指向的数据类型:int **
- 指针能够访问到的内存空间的大小 :由他指向的数据类型决定
(1)Int a =10;
Int *p =&a;//*p能够访问到的内存空间的大小为4字节
- char b = ‘a’;
Char *p = &b;//*p能够访问到的内存空间的大小为1字节
- int *p = NULL;
Int **pp = &p;//*pp能够访问到的内存空间的大小为4字节
//pp指向的数据类型int * : 所以他能够访问到的内存空间的大小为4字节
4、
Int ** n = NULL; //n的数据类型:int **
Int ** * m = &n; //m指向的数据类型int**
6.10指针的算数运算
p+n:p+n相当于向地址增大的方向移动了n个数据
实际的变化:p + sizeof(指针指向的数据类型)* n
(p的指向没有发生改变)
- n: p-n相当于向地址减小的方向移动了n个数据
实际的变化:p - sizeof(指针指向的数据类型) * n
(p的指向没有发生改变)
p++:p向地址增大的方向移动的一个数据(p的指向发生了改变)
p--: p向地址减小的方向移动了一个数据(p的指向发生了改变)
p-q:(p和q的数据类型一致):这两个指针之间相隔的数据的个数
注意:
- 指针的算术运算只有在操作连续的内存空间时,才有意义!
- p是一个指针变量,以上的操作方法对指针常量也适用,但是++、--除外
7.函数
7.1、概念
具有独立功能的模块
7.2、为什么要使用函数
1、使代码模块化
2、提高代码的复用率
7.3、函数的分类
7.3.1 库函数
printf 、scanf 、strlen 、strcat......
7.3.2 引入头文件
#include <stdio.h>、 #include<string.h>
7.3.3 调用函数
Strlen(数组名);
函数名(实际参数);
返回值:字符串的实际长度;考虑:返回值的数据类型,以及返回值是否需要
(如果需要使用函数的返回值:定义一个与其返回值相同的数据类型去接收!)
7.3.4自定义函数
函数定义
存储类型 数据类型 函数名(形式参数列表)
{
函数体;//具体功能的实现
返回值;
}
存储类型:static、extern
数据类型:函数返回值的数据类型(函数返回值:不写默认为:int)
函数名:见名知意(满足标识符的命名规则)
形式参数列表:实现功能所需要的参数,需要调用者传入
函数体:具体功能的实现
返回值:若没有返回值,返回值可以省略(类型:void),如果有返回值:有且只能有一个!
调用函数
函数名(实参列表);
注意:
- 需要将实参的值传递给形参,实参的个数和数据类型必须和形参一致
- 实参,可以是常量、变量、表达式,但必须是一个确定的值;
- 实参和形参是两块独立的空间(因此可以重名)
- 传参实际上是将实参的值拷贝给形参
- 形参是局部变量,在函数调用时开辟空间,调用结束立即释放
函数声明
如果函数没有在main函数之前,就需要在main函数之前添加声明;
声明方法:将函数头直接拷贝到main函数之前,然后加上分号;
未加声明之前:
7.4字符串的处理函数
7.4.1 求字符串的长度
strlen(数组名);
功能:求字符串的实际长度
返回值:求得的字符串的实际长度,不包含‘\0
Strlen和sizeof的区别
- strlen是函数,sizeof是运算符
- Strlen求到的是字符串的实际长度,不包含‘\0’,sizeof求到的是整个空间的大小
案例:不使用strlen:求字符串的实际长度
7.4.2 字符串的拷贝函数
Strcpy(数组1,数组2/字符串);
功能:将数组2中的内容拷贝到数组1中,包含‘\0’,相当于完全拷贝
注意:数组1的容量大于数组2
7.4.3 字符串连接函数
Strcat(数组1,数组2/字符串);
功能:将数组2或者字符串的内容连接到数组1中,数组1中的‘\0’会被覆盖
注意:数组1的容量要大一些
7.4.4 字符串的比较函数
Strcmp(数组1/字符串1,数组2/字符串2);
功能:比较字符串1和字符串2的大小
返回值:
大于0:字符串1 > 字符串2
等于0:字符串1 == 字符串2
小于0:字符串1 < 字符串2
比较规则:
从左往右一次对字符串中的字符的ascii码值进行比较,直到遇到不同的ascii值或者遇到‘\0’结束比较