小小白学习c语言——动态申请&宏定义&结构体

本文围绕C语言展开,介绍了动态内存分配,需引用库函数,在堆区申请和释放空间;讲解宏定义,可代表常量、变量等,带参宏使用时要注意运算符优先级;还阐述了const和static的用法,以及extern关键字的作用;最后详细介绍了结构体,包括定义、变量使用、初始化等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.动态内存分配

        为什么要动态申请内存?

      有些函数在调用时需要传递参数,比如数组的地址,如果我们在函数里只用静态申请数组的话会使程序的可移植性降低,为了灵活使用函数,所以会用到动态申请。

        使用动态申请前,需要先开空间再使用。

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

        调用前需用引用库函数:<stdlib.h>

        申请空间:malloc

        释放空间:free

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

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

        申请2个int型的空间大小,对空间进行写数据,然后读数据

#include<stdio.h>
#include<stdlib.h>
void *malloc( size_t size );
void free( void *ptr );
int main(void)
{
	int *p = (int *)malloc(sizeof(int)*2);
	
	*p = 100;
	*(p+1) = 200;
	
	printf("%d %d\n",*p,*(p+1));
	
	free(p);
	//p = NULL;
	printf("%d %d",*p,*(p+1));

	return 0;
}

如果p=NULL省略,可以明细观察到下面不清零的情况

p=NULL不省略会出现以下情况

2.宏定义

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

#define+宏名+代表内容

“#”代表预处理符号 预处理阶段进行替换

>>宏定义的好处:方便代码的维护,一改全改;

#include<stdio.h>

预处理阶段进行 宏替换常量 变量以及表达式

#define bookNum 2000

#define NUM

#define ADD c+d

带参宏

 #define 宏名(参数列表,不写类型)  表达式

#define GETHE(x,y) x + y

宏定义后面表达式的时候,为了避免运算符优先级,最好加括号()

#define SUB(x,y) (x-y)

使用宏明代表类型

给类型起别名  u8 u16 u32   unsigned char

#define u8 unsigned char

使用宏名写一个表达式求两个数中的最小值

#define Min(x,y) (x < y ? x : y)0

预处理:

#include   拷贝

 #define   宏替换

 #if #else  条件编译

编译:  检查语法错误

汇编:  生成二进制代码

链接:  链接静态动态库  根据不同的平台+不同平台的启动代码

3.顺便说一下const 和 static

const 修饰变量后,变量的值不能被修——变量只读;

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

int a=30;

a=50;

const int b=60;//const 变量必须初始化 或者 int const c=80;

const 和指针

char str1[30] = "hello world";

char str2[30] = "xxxxx";

str1[0] = '8';        //修改str1的第一位,把h变成8

// const在*的前面修饰的是指针指向的空间 *p

// p空间没有限定

const char *p = str1;

printf("%s\n",p);

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

p = str2;    // p是可以读写的

printf("%s\n",p);

// const放在*之后修饰的是指针本身的空间  p

// 必须要初始化,不然后面就用不了指针,不能再改变他的指向

char *const q = str1;

printf("%s\n",q);

// q = str2;  // 错误 报错 q是只读

*q = 'i';     // *q可以读写

printf("%s\n",q);

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

const char *p = str1;

char *const q = str1;

const char *const p = str1;

// p和 *p都是只读的。

const char *p = str1;

char const *t = str1;  // *t是只读的,t是可以读写

!!!! cosnt int *p和 int const *p有什么区别?  没区别 !!!!​​​​​​​

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

4.还有讲一下这个​​​​​​​​​​​​​​extern关键字

extern int m;  // 变量声明

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

5.结构体

5.1 数据类型——自定义类型

在写结构体之前 一定要理清楚应该需要些哪些成员名字以及成员类型!

比如:

班级同学的信息:

        姓名        性别     年龄     成绩  

        李天        男       20       94.5

        张三        男       19       65

        ···········

类型:字符串    字符串   整型     实型

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

汽车: 品牌  价格  颜色 ...

电脑: 品牌  价格  颜色  CPU  memory

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

​​​​​​​5.2 定义结构体数据类型

格式:

struct  结构体名称

{

        成员类型 成员名;

        成员类型 成员名;

        成员类型 成员名;

        成员类型 成员名;

        。。。。。

};

例子:

图书:图书编号   书名            作者         热度     价格

              int         char [40]    char [30]        int      float

输出成这样:

结构体类型名:struct book

struct book

{

        int num;

        char name[40];

        char author[30];

        int hot;

        float price;

};

5.3 typedef

以前使用数据类型 --- 数据类型关键字只有一个单词。

typedef ---- 给类型起别名。

typedef 数据类型 别名;

比如:

typedef unsigned char u8;

#define u8 unsigned char

举个例子:

typedef struct book

{

        int num;

        char name[40];

        char author[30];

        int hot;

        float price;

}BK;

结构体类型名:struct book

typedef struct book BK;

BK 就是 struct book,是数据类型

5.4 结构体变量

先定义再使用

typedef struct book

{

        int num;

        char name[40];

        char author[30];

        int hot;

        float price;

}BK;

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);

定义类型后直接定义变量

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

tips:

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

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

————————————————————————————————

5.5结构体变量初始化

!!!按照成员定义的顺序赋值 不能跳跃!!!

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};

5.6​​​​​​ 结构体变量间可以通过 = 赋值
#include<stdio.h>

	struct book
	
	{
	
		int num;
	
		char name[40];
	
		char author[30];
	
		int hot;
	
		float price;
	
	}b3={1,"C语言","",5,34.5};

int main()
{
	struct book b4;
	b4 = b3;
	printf("%d %s %s %d %.2f",b4.num,b4.name,b4.author,b4.hot,b4.price);		

	return 0;
}

5.7 结构体指针

最难的指针来了!

结构体类型* 指针名;

用指针找到对应地址然后输出对应值

成员访问符号  ->   

p->num --- int

p->name  --- 数组名

p->author --- 数组名

p->hot   ---- int

p->price ---- price

#include<stdio.h>
	
struct book
{

	int num;
	
	char name[40];
	
	char author[30];
	
	int hot;
	
	float price;

};



int main()
{
	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);

	return 0;
}

Last but not least:

Ending!!!

脑袋发蒙了!!

已经不想再思考了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值