动态申请–宏定义–结构体
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