C语言第六天

1 函数的定义和使用

返回值类型 函数名称(形式参数列表)
{
函数代码;
return 返回值;
}
函数的作用:通常我们有一个有名字的函数代替一段代码。
1 能够具有复用性(重复的使用已经定义好的代码)。
2 能够将功能进行拆分,使得程序的编写更具有逻辑性。

2 局部变量和全局变量

局部变量:定义在函数内部的变量。只在{}内是有效的。
全局变量:定义在函数外部的变量。可以被所有的函数所共用。

int main()
{
	int a = 10;
	if (a>=10)
	{

		int b = 20;
		printf("%d", b);
	}
	//for循环第一条语句定义的变量,属于for的复合语句
	//在for的外面,无法使用
	//如果说渐变量还想在后面继续使用,应该定义在for之前
	int i = 0;
	int j = 0;
	for (int i = 0; i < 100; i++,j++)
	{
		j++;
		printf("%d", i);//当作用域较大的变量和作用域较小的变量重名的时候
		                //在小作用域内使用的是自己作用域的变量。
	}
	if (i==100)
	{

	}
	//printf("%d", b);不能使用
	printf("%d", a);
	return 0;
}

3 extern的作用

声明一个变量 声明了之后,就可以使用。
extern的作用也可以认为是 后面的变量不是在我这里定义的,请编译器去别的地方找到它。

在我们声明或者定义变量函数的时候,经常会出现这样的一个错误:
在这里插入图片描述
出现这样的错误,就说明:
a 只有声明,没有实现。
b 声明和实现不匹配。

4 static的作用

修饰全局变量或者函数的时候: 隐藏的作用,此全局变量或者函数只能在本文件中使用
修饰局部变量的时候:静态的作用,离开函数时,依然保留数值不销毁,下次函数使用上一次保留的值。

5 const的使用

const int a =10;
const类型的常量必须初始化。

int main()
{
	const int num = 100;
	//const int num1;必须有初始值
	return 0;
}

6 指针的基本使用

1 定义指针变量
2 给指针变量赋值
3 解引用

int main()
{
	int nNum = 100;
	int nNum2 = 100;
	int * p = NULL;
	
	p = &nNum;//指针变量存储了谁的地址,它就指向了谁

	*p = 200;//解引用,访问指向的位置

	printf("%d\n", nNum);

	p = &nNum2;

	printf("%d\n", *p);

	scanf_s("%d", p);

	//scanf_s("%d", &(*p));//和上面的语句一样的
	printf("%d", nNum2);

	return 0;
}

关于结构体:

如果说,我们实现了一个学生系统,要存储学生的信息。那么如果和一名学生有关的信息,都是单独的去定义变量的话,那么维护起来,就会比较麻烦。
我们有一个简单的方法能够解决这样一个问题。

int main()
{
	int nAge1 = 18;
	double dHeight1 = 175.5;
	int nSocore1 = 98;

	int nAge2 = 20;
	double dHeight2 = 168.5;
	int nSocore2 = 95;

	int nAge3 = 20;
	double dHeight3 = 168.5;
	int nSocore3 = 95;

	int nAge4 = 20;
	double dHeight4 = 168.5;
	int nSocore4 = 95;


	int nAge5= 20;
	double dHeight5 = 168.5;
	int nSocore5 = 95;


	int nAge6 = 20;
	double dHeight6 = 168.5;
	int nSocore6 = 95;

	return 0;
}

这种语法就是结构体,以下是结构体变量的基本用法:

int main()
{
	//定义结构体变量
	struct {
		char szName[20];
		int nAge;
		double dHeight;
		int nScore;
		int nGender;
	}stcXiaomingInfo;
	//使用结构体变量,是通过.来访问结构体中的成员(字段)的
	//使用某一个成员的时候,它是什么类型,就按照什么类型来使用
	 strcpy_s(stcXiaomingInfo.szName, 20, "xiaoming");
	 stcXiaomingInfo.nAge = 18;
	 stcXiaomingInfo.dHeight = 175.5;
	 stcXiaomingInfo.nGender = 1;
	 stcXiaomingInfo.nScore = 98;

	 //结构体变量的初始化
	 struct {
		 char szName[20];
		 int nAge;
		 double dHeight;
		 int nScore;
		 int nGender;
	 }stcXiaohongInfo = {"xiaohong",20};


	 struct {
		 char szName[20];
		 int nAge;
		 double dHeight;
		 int nScore;
		 int nGender;
	 }stcXiaoheiInfo = { "xiaohei",20 };

	return 0;
}

按照如上的方式使用结构体,比较麻烦。定义结构体变量有简单的方法:

struct STUINFO{     //STUINFO是类型名
	char szName[20];
	int nAge;
	double dHeight;
	int nScore;
	int nGender;
};//结构体变量名
int main()
{
	int nNum;
	//定义结构体变量
	STUINFO stcXiaomingInfo;
	//使用结构体变量,是通过.来访问结构体中的成员(字段)的
	//使用某一个成员的时候,它是什么类型,就按照什么类型来使用
	 strcpy_s(stcXiaomingInfo.szName, 20, "xiaoming");
	 stcXiaomingInfo.nAge = 18;
	 stcXiaomingInfo.dHeight = 175.5;
	 stcXiaomingInfo.nGender = 1;
	 stcXiaomingInfo.nScore = 98;

	 //结构体变量的初始化
	 STUINFO stcXiaohongInfo = {"xiaohong",20};
	 STUINFO stcXiaoheiInfo = { "xiaohei",20 };

	 //给xiaohei 从键盘上输入身高,性别,分数
	 printf("请输入身高");
	 scanf_s("%lf", &stcXiaoheiInfo.dHeight);
	 printf("请输入性别");
	 scanf_s("%d", &stcXiaoheiInfo.nGender);
	 printf("请输入分数");
	 scanf_s("%d", &stcXiaoheiInfo.nScore);
	 printf("请输入姓名");
	 scanf_s("%s", &stcXiaoheiInfo.szName,20);

	 //输出xiaoming和xiaohei的信息
	 printf("%s %d %lf %d %d", stcXiaomingInfo.szName,
		 stcXiaomingInfo.nAge, stcXiaomingInfo.dHeight,
		 stcXiaomingInfo.nGender, stcXiaomingInfo.nScore);

	 printf("%s %d %lf %d %d", stcXiaoheiInfo.szName,
		 stcXiaoheiInfo.nAge, stcXiaoheiInfo.dHeight,
		 stcXiaoheiInfo.nGender, stcXiaoheiInfo.nScore);


	return 0;
}

关于结构体嵌套和结构体数组的使用:

struct STUINFO{     //STUINFO是类型名
	char szName[20];
	int nAge;
	double dHeight;
	int nScore;
	int nGender;
};//结构体变量名
struct POINT
{
	int x;
	int y;
};
//结构体的嵌套
struct CIRCLE
{
	POINT stcCirPoint;
	double r;
};
int main()
{
	STUINFO stcStuArray[5] = { 0 };
	//循环遍历输入学生的信息
	for (int i = 0; i < 5; i++)
	{
		printf("请输入学生的信息:");
		scanf_s("%s %d %lf %d %d",
			stcStuArray[i].szName, 20,
			&stcStuArray[i].nAge, &stcStuArray[i].dHeight,
			&stcStuArray[i].nScore, &stcStuArray[i].nGender);
	}
	//结构体的嵌套
	POINT pt = { 10,20 };
	CIRCLE  yuan;
	yuan.stcCirPoint.x = 100;
	yuan.stcCirPoint.y = 200;
	scanf_s("%d", &yuan.stcCirPoint.x);
	return 0;
}

联合体:

联合体的使用语法,和结构体一摸一样的。
区别:
联合体所有的成员共用内存空间。
结构体的每一个成员独占内存空间。
在这里插入图片描述
联合体有什么用??节省空间

#define 小学生  1
#define 初中生  1
#define 高中生  1

struct STUINFO {
	char  szName[20];
	int nAge;
	int nTpye;
	union {
		char  szParentTel[20];
		char  szSelfTel[20];
		char  szId[20];
	}SpecialInfo;

};
int main()
{
	STUINFO  xiaoming = { "xiaoming" };
	xiaoming.nAge = 7;
	xiaoming.nTpye = 小学生;
	scanf_s("%s", xiaoming.SpecialInfo.szParentTel, 20);
	return 0;
}

类型的定义:

typedef和结构体的连用属于是一个历史遗留问题

//类型定义

//typedef  能够给一个类型重新名一个名字
typedef int INT;

typedef struct _INFO
{
	char szName[20];
	int nAge;
	int nId;
}INFO;

struct  TEST
{
	int a;
	int b;
};

int main()
{
	struct _INFO  stc;//C语言的写法

	INFO nihao;

	TEST obj;
	return 0;
}

堆空间:

我们需要一种能够在程序运行的期间,动态的决定,存储数据空间大小的能力。
我们需要借助malloc这个函数。
申请到的地址 malloc (你需要多大内存);

int main()
{
	//我想申请能够存储10个整数的空间
	//然后遍历输入
	//遍历输出
	int *p = NULL;
	p = (int *)malloc(10 * sizeof(int));

	//我们使用指针和数组是非常类似的
	//输入
	for (int i = 0; i < 10; i++)
	{
		printf("请输入一个数:");
		scanf_s("%d", &p[i]);
	}
	//输出
	for (int i = 0; i < 10; i++)
	{
		printf("%d ",p[i]);
	}

	free(p);
	p = NULL;


	return 0;
}

}

数组和堆有什么区别:

1 数组的长度,是常量, 堆的大小,可以是变量
int main()
{
	int n = 0;
	int *p = NULL;
	printf("你需要存储多少个整数:");
	scanf_s("%d", &n);
	//int Arr[n];//数组长度必须是常量
	p = (int *)malloc(n * sizeof(int));
	//将一块内存,设置为一个值
	memset(
		p,//起始地址
		0, //要设置的值
		n * sizeof(int)
	);
	return 0;
}

2 数组由系统自己释放,堆需要由我们自己释放
int main()
{
	int n = 0;
	int *p = NULL;
	printf("你需要存储多少个整数:");
	scanf_s("%d", &n);
	//int Arr[n];//数组长度必须是常量
	while(1)
	{
		//p = (int *)malloc(n * sizeof(int));
		int Arr[1024];
	}
	return 0;
}

悬空指针和野指针

悬空指针:释放了,但是没有被置为NULL的指针
释放完的指针,应该及时被置为NULL
野指针:没有被初始化的指针,就是野指针。
使用悬空指针或者使用野指针,都会造成程序崩溃。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值