C语言学习 动态申请--宏定义--结构体

动态申请–宏定义–结构体

1、动态内存分配

先开空间再使用

如果遇到需要再程序运行是根据需求空间,可以用动态内存申请。

例如:图书管理系统 — 图书信息— 图书的数量是动态变化的 — 动态内存申请图书空间,存储图书信息。

动态内存申请的空间在 堆区 ,堆区空间人为申请,人为释放。

库函数 stdlib.h

申请空间函数:malloc

释放空间:free

函数申明:void *malloc( size_t size );

函数功能:申请size个字节大小的空间,返回空间的首地址。

使用例子:

//申请一个int型的空间
int *p
p = (int *)malloc(sizeof(int));

*p = 30;
printf("%d",*p) //输出 -- 30
//释放空间: voie free(void *ptr)
free(p);
p = NULL; //防止野指针

2、宏定义

定义一个标识符代表 常量数字 变量 表达式 来使用

#define 宏名 代表的内容

#—预处理符号 预处理阶段进行宏替换

宏定义方便代码的维护 ,一改全改

#include <stdio.h>

#define BOOKNUM 2000
#define NUM n
#define ADD c+d
//带参宏 宏名(参数列表,不写类型) 表达式
#define GETSUM(x,y) x+y

//宏定义后面是表达式的时候,为了避免运算符优先级,最好加()
#define SUB(x,y) (x-y)

//使用宏名代表类型 --- 给类型起别名  例如 
#define u8 unsigned char  //给 unsigned char类型起别名叫 u8

//使用宏名写一个表达式求两个数中的最小值
#define MIN(x,y) (x<y?x:y)

int main() {
	int a = BOOKNUM + 1000;
	printf("%d %d",a,BOOKNUM)//输出 -- 3000 1000
	
	int n = 30;
	printf("%d",NUM);	//输出 -- 30
	
	int c = 90;
	int d = 100;
	printf("%d",ADD); //输出 -- 190
	printf("%d",GETSUM(c,d)) //输出 -- 190
	
	// 用宏定义小心, 程序不会做运行 -- 只会替换
	printf("%d\n",3*GETSUM(c,d)); // printf("%d\n",3*c+d); //输出 -- 370
	printf("%d\n",3*SUB(c,d));   // printf("%d\n",3*(c-d));//输出 -- -30
    
    int res = MIN(c,d); 
    printf("%d",res) //输出 -- 90 
}

3、const 和 static

3.1 const关键字

const修饰变量后,变量的值不能被修 – 变量只读。

const变量在定义时候就要给值,即const变量必须初始化。

int a = 30;
a = 50; 

const int b = 60;
//或者
int const c = 60;

const和指针

char str1[30] = "hello world";
char str2[30] = "你好世界"
// const在*的前面修饰的是指针指向的空间 *p
// p空间没有限定
const char *p = str1;
printf("%s\n",p); //输出 -- hello world 

// *p = 'o'; // 报错 *p是只读 

p = str2;    // p是可以读写的
printf("%s\n",p); //输出 -- 你好世界 

// const放在*之后修饰的是指针本身的空间  p
// 必须要初始化,不然后面就用不了指针,不能再改变他的指向
char *const q = str1;
printf("%s\n",q); //输出 -- hello world

// q = str2;  // 错误 报错 q是只读
*q = 'i';     // *q可以读写
printf("%s\n",q);	//输出 -- iello world

--------------------------------------------
const char *const p = str1;
// p和 *p都是只读的。

const char *p = str1;
char const *t = str1;  // *t是只读的,t是可以  两种写法是一样的

3.2 static 关键字 – 静态

static – 局部变量:变量只能初始化一次,位于静态数据区,函数结束空间不会被销毁

– 全局变量:变量只能当前文件里面使用

– 函数: 函数只能在当前文件里面使用

修饰局部变量

#include<stdio.h>

void test(void)
{
	static int a = 1;
	printf("%d\n",a);
	a++;

int main()
{
	test();  // 1
	// 静态数据区 -- a = 1  a++ ;  a=2
	test();  // 2
		// static int a = 1; --- 检测到静态数据区已经开过空间了,忽略这一条指令
		//  输出 2  a++   a=3
	test(); // 3
		// static int a = 1; --- 检测到静态数据区已经开过空间了,忽略这一条指令
		//  输出 3  a++   a=4
		
	// printf("%d",a); 报错 a 没有定义 ,不能访问,并没有改变a是静态局部变量的属性。 
	return 0;
}

3.3 extern 关键字

extern int m; // 变量声明

在使用的地方对变量声明,程序运行的时候回去别的文件里面查找这个变量。

4、结构体

数据类型 – 自定义数据类型

结构体是一种自定义的数据,将多个不同数据类型的数据放在一起形成一个新的数据类型。

例如:

汽车: 品牌 价格 颜色 …

电脑: 品牌 价格 颜色 CPU memory

按照需求先创造数据类型,之后使用创建的数据类型开空间,存取数据。

4.1 定义结构体数据类型

格式:

struct 结构体名称

{

成员类型 成员名;

成员类型 成员名;

成员类型 成员名;

成员类型 成员名;

。。。。。

};

例:

//举例:
//		图书:图书编号  书名          作者          热度     价格
//			 int      char [40]    char [30]    int      float	
struct book
{
  int num;
  char name[40];
  char author[30];
  int hot;
  float price;
};

//结构体类型名: struct book

4.2 typedef

typedef —— 给类型起别名

格式: typedef 数据类型 别名;

typedef struct book
{
  int num;
  char name[40];
  char author[30];
  int hot;
  float price;
} BK;
//BK就是struct book,是数据类型
struct book a;
BK b; //两者都是等价的

typedef也可以对一个数据类型其多个别名

typedef struct book
{
  int num;
  char name[40];
  char author[30];
  int hot;
  float price;
} BK,BKOth;
BK = a;
BKOth = b; //两者都可以定义struct book类型的变量

4.3 结构体变量

4.3.1 先定义再使用

结构体变量通过 . 语法找到成员

struct book = a;
//结构体变量通过 . 语法找到成员
//a.num --- int 
//a.name --- 数组名
//a.author --- 数组名
//a.hot   ---  int 
//a.price --- float 			

a.num = 1;
strcpy(a.name,"C语言");
strcpy(a.author,"树懒大人");
a.hot = 4;
a.price = 36.5;

printf("%d %s %s %d %.2f",a.num,a.name,a.author,a.hot,a.price)
//输出 —— 1 C语言 树懒大人 4 36.5

通过用户键盘输入赋值

printf("请输入图书编号:");
scanf("%d",&a.num);
printf("请输入书名:");
scanf("%s",a.name);
......
4.3.2 定义类型直接定义变量
struct book
{
	int num;
	char name[40];
	char author[30];
	int hot;
	float price;
}b1,b2
//b1.num --- int 
//b1.name --- 数组名
//b1.author --- 数组名
//b1.hot   ---  int 
//b1.price --- float 

//b2.num --- int 
//b2.name --- 数组名
//b2.author --- 数组名
//b2.hot   ---  int 
//b2.price --- float 				

注意:结构体定义如果前面有 typedef 后面是类型别名。

结构体定义如果前面没有typedef 后面是变量

4.3.3 结构体变量初始化
//按照成员定义的顺序赋值 不能跳跃
			
struct book
{
	int num;
	char name[40];
	char author[30];
	int hot;
	float price;
};

struct book b1 = {1,"C语言","",5,34.5};
struct book b2 = {1,"C语言","",5};

--------------------------------------------------------------

struct book
{
	int num;
	char name[40];
	char author[30];
	int hot;
	float price;
}b3={1,"C语言","",5,34.5
4.3.4 结构体变量间可以通过 = 赋值
struct book
{
	int num;
	char name[40];
	char author[30];
	int hot;
	float price;
}b3={1,"C语言","",5,34.5};

struct book b4;
b4 = b3;
printf("%d %s %s %d %.2f",b4.num,b4.name,b4.author,b4.hot,b4.price);
//输出 —— 1 C语言  5 34.5

4.4 结构体指针

结构体指针通过 -> 访问成员

p->num — int

p->name — 数组名

p->author — 数组名

p->hot ---- int

p->price ---- price

struct book b1 = {1,"C语言","",5,34.5};
struct book* p;
p = &b1;

printf("%d %s %s %d %.2f",p->num,p->name,p->author,p->hot,p->price);
//输出 —— 1 C语言  5 34.5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值