目录
一.函数
1.1函数的定义
什么是函数?
函数就是将实现某种功能的代码块封装成一个整体,当想重复实现某种功能时就可以调用这个
整体代码块的名字即可。
1.2函数的定义
返回值类型 函数名(形式参数列表){
函数体;
}
1.2.1简单的函数使用
#include<stdio.h>
int compare(int x,int y);//函数声明,该函数使用时需要两个int类型的参数,并且在结束时
需要返回一个int类型的值
//比较两个数的大小
int main(){
int a,b;
scanf("%d",&a);
scanf("%d",&b);
printf("%d\n",compare(a,b));
return 0;
}
//函数定义
int compare(int x,int y){
return x>y?x:y;
/*三目运算符 表达式1?表达式2 : 表达式3
表达式1的值为真,则整个表达式的值与表达式二的值相同
为假则与表达式3的值相同
*/
}
解释:
函数声明:指明了函数的返回值类型与函数接收形式参数的类型以及形参个数。在没有函数声明时切该函数的定义在main函数之下时,运行程序时会出现找不到该函数警告或者错误,这时就需要用到函数声明了,函数声明需要在main函数之前。在编程时无论用到用不到该函数都建议加上函数声明,以便养成良好的编程习惯。
返回值类型:函数的返回值是函数执行完成后返回给调用者的结果。
形式参数:在函数声明时定义的参数,用于接收调用者传递给函数的数据。
实际参数:是出现在函数调用括号中的表达式。
例如:调用compare(int x,int y), x和y就是形式参数 ,main函数调用时传入了两个int类型的
变量 a,b。这两个变量a,b就是实际参数
//下面以一个小例子来加深印象
//计算两个整数之间的和,使用函数并返回值
#include<stdio.h>
int sum(int x,int y);//函数声明,在调用该函数时需要传入两个int类型的参数
int main(){ //主函数,无论程序多么复杂程序都是从main函数开始执行的
int num1,num2;//定义两个int类型的变量,操作系统会为这两个变量分配内存空间,未初始化,
//这时变量里面的值是随机的
scanf("%d%d",&num1,&num2);//给变量num1,num2初始化
printf("%d\n",sum(num1,num2));//调用sum(int x,int y)函数并传入了两个参数,计算完
//两个数之和后会返回一个int类型的值
/*这一步可以拆解为一下两步
int i=sum(num1,num2);
printf("%d",i);
*/
return 0;
}
int sum(int x,int y){ //调用函数函数时会将实际参数传递给函数里的形式参数,可以这样理解
//int x=num1; int y=num2;
//在操作系统也会给函数以及函数里面的变量分配内空间
int num=0;//用来接收两个数之和的变量
if(x<y){
for(int i=x;i<=y;i++){
num+=i;
}
return num;
}else{
for(int i=y;i<=x;i++){
num+=i;
}
return num;
}
}
1.3全局变量与局部变量
全局变量:可以粗略的理解为定义在 花括号“ {} ”外的变量
生命周期:
在main函数执行之前创建完成,并且在程序运行期间都不会被操作系统回收。
作用域:整个源文件都可以使用
局部变量:可以粗略的理解为在 “ {} ”内定义的变量,
生命周期:
在程序运行到变量所在的位置被创建,在程序出{}后操作系统给局部变量分配的内存空间被回收。
作用域:最近的{}内,出了最近的花括号就被销毁
1.3.1全局传参(了解)
#include<stdio.h>
int num1,num2;
void num_add();//代表不需要传入参数
int main(){
scanf("%d%d",&num1,&num2);//初始化全局变量num1,num2的值
//把初始化的值进行自增
num1++;
num2++;
//调用函数
num_add();
printf("%d\n",num1+num2);//相加输出
return 0;
}
void num_add(){
//接着自增
num1++;
num2++;
}
1.3.2地址传参(地址传递)
如果在函数中想修改实参的值,就需要把实参的地址传递给函数
#include <stdio.h>
void my_swap(int *x, int *y);//返回值为空,参数需要传入两个int变量的地址
int main(){
int a = 10;
int b = 20;
my_swap(&a, &b);
printf("a = %d b = %d\n", a, b);// 20 10
return 0;
}
void my_swap(int *x, int *y){ //相当于int *x=&a, int *y=&b
int temp = 0;//创建一个临时变量,用于保存值。实现两个变量值的交换
temp = *x; //*x表示取指向地址的值,然后把值赋值给temp。
*x = *y; //它的意思是把x指向地址的值改变为y指向地址的值
*y = temp; //把y指向地址的值改变为temp的值
//交换两个变量的值已实现 结束!!!
}
1.3.3字符串传参
字符串传参时,只需要传首地址即可,因为字符串都有'\0'作为结束的标志
//strcpy实现:
#include<stdio.h>
char *my_strcpy(const char *,char *);
int main(){
char name[]="liming";
char name2[]="zhangsan1";
my_strcpy(name,name2);
printf("%s\n",name);
printf("%s\n",name2);
return 0;
}
char *my_strcpy(const char *source,char*desc){
char *temp=desc;//需要备份一下desc的首地址,作用是等字符串复制完之后,
//将这个地址返回,返回的这个地址是新的字符串的首地址(字符串拷贝,地址并没有改变)
while(*source!='\0' ){ //只要取出的源字符不为 '\0' 则进进入while循环
*desc++=*source++;
/*可以拆解为两步
1. *desc=*source; //把desc指向地址里面的内容改变为source指向地址里的内容
2. desc++;
source++;
*/
}
*desc=*source; //最后source指向字符串的结尾 ’\0',
//把desc的指向地址里面的数据修改为source指向地址里面的的数据
return temp;
}
二.typedef与malloc函数的使用
2.1typedef的作用
typedef是给某个类型起别名的。
例如:
typedef int INT;//给int 起了一个别名INT,在程序中定义变量和int定义变量一样
INT num;//定义了一个int类型的变量
2.2malloc函数
函数原型;void *malloc(size_t size);
功能:在堆区分配空间
参数:size 就是要分配的空间的大小 单位是 字节
返回值:成功返回分配的空间的首地址 失败返回 NULL
注意:在使用完成之后需要程序员手动进行空间释放
2.3typedef与malloc的使用
#include<stdio.h>
#include<stdlib.h> //malloc 使用需要引入stdlib头文件
typedef int i;
int main(){
i *p=(i*)malloc(sizeof(i));/*使用malloc在堆区分配一块内存空间,并且使用指针保存这片空间的首地址,
这里的 i 就是int,只不过是使用typedef对int起了个别名*/
//使用malloc建议判断一下分配空间是否成功
if(NULL==p){
printf("空间分配失败");
}
scanf("%d",p);
printf("%d",*p);
//在使用完这片空间之后手动回收堆区中的内存空间
free(p);
return 0;
}
三.enum与结构体
3.1enum枚举类型
枚举类型:使用enum关键字可以创建新的“类型”,这个“类型”里面的数据默认值为0,后面的值依次加一
格式:
enum 枚举类型名{
成员1,成员2,成员3 , ... ,成员n
};
/* 1.枚举类型中成员1如果没有被赋值,默认初始值是0
2.后面的成员在该值的基础上依次+1
3.如果某个成员被赋了初始值,那么后面的成员在这个值的基础上依次+1
4.枚举一旦定义好了 成员都是 常量*/
3.1.1enum的使用
例如:
#include<stdio.h>
enum color{
red,yellow,orang,green=100,blue
};
int main(){
enum color c1,c2,c3,c4,c5;//创建5个枚举类型的变量
c1=red;//给枚举变量初始化
c2=yellow;
c3=orang;
c4=green;
c5=blue;
//分别输出枚举变量的值,观察枚举变量的值
printf("c1=%d\n",c1);
printf("c2=%d\n",c2);
printf("c3=%d\n",c3);
printf("c4=%d\n",c4);
printf("c5=%d\n",c5);
//枚举类型的大小
printf("枚举类型的大小:%ld\n",sizeof(enum color));
return 0;
}
3.2结构体
结构体定义:
struct 结构体名{
数据类型 变量名1;
数据类型 变量名2;
数据类型 变量名3;
数据类型 变量名4;
数据类型 变量名5;
};
注意:
1.成员之间用 分号 分隔
2.结构体的成员在内存上是连续的(涉及内存对齐)
3.结构体变量之间可以直接相互赋值
4.结构体也可以定义数组:struct 结构体类型名 数组名[下标];
3.2.1结构体成员的访问
#include<stdio.h>
#include<string.h>
//结构体
typedef struct __STUDENT{
int id;
char name[32];
int score;
}stu;
//以下示例中使用了两种方法来访问结构体成员
int main(){
stu student;
student.id=1;
stu *p=&student; //struct __STUDENT类型的指针指向变量名为student的地址
strcpy(p->name,"liming");//注意字符串赋值需要使用strcpy()函数,函数说明 char *strcpy(char *dest, const char *src);
p->score=99;
printf("%d\n",p->id);
printf("%s\n",p->name);
printf("%d\n",p->score);
return 0;
}
/*在 C 语言中,使用.操作符和->操作符来访问结构体的成员,取决于您操作的是结构体变量还是指向结构体的指针。
如果使用的是结构体变量,那么访问结构体成员时使用 变量名.结构体成员 来访问
如果使用的是结构体指针的话那么则使用 指针变量名->结构体成员 来访问
因为指针本身并不包含结构体的成员,->操作符首先解引用指针,然后使用.操作符来访问结构体的成员。
*/
四.union联合体
4.1union的使用
1.union是一种数据类型,union可以在空一块空间存储不同类型的值。union的大小取决于最大的成员。
2.虽然联合体元素公用一片内存空间,在使用时只能访问一个成员
例如:
#include<stdio.h>
#include<string.h>
union hold{
int id;
char name[32];
double money;
};//创建了一个结构体
int main(){
union hold h;
//测试结构体,给每一个成员都赋值,然后书橱看现象
h.id=10;
strcpy(h.name,"liingaughu");
h.money=10.00;
//访问元素,发现只能访问最近使用的那一个元素的值
printf("%lf\n",h.money);
printf("%d\n",h.id);
printf("%s\n",h.name);
printf("%ld\n",sizeof(union hold));//结构体的大小取决于最大成员的大小
return 0;
}