百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

C语言中结构体、变量的作用域和mem函数的使用

liebian365 2024-11-16 23:09 22 浏览 0 评论

1.指针中memset函数

memset主要功能就是将一块内存设置为0,即参数2设置为0

Bash
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>

int main13_01()//memset(a,b,c);  a是置空首地址,b通常写0,c这块内存大小
{
	int a[10] = { 10,1,2,3,4,5,6,7,8,9 };
	int* p = a;
	memset(a, 0, sizeof(*p));//将a这个地址40个字节设置为0
	for (int i = 0; i < 10; i++)
	{
		printf("a[%d]=%d\n", i, a[i]);
	}
	return 0;
}

2.memcpy函数

Bash
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main13_02()//memcpy()
{
	short a[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int b[10] = { 0 };
	memcpy(b, a, sizeof(a));
	for (int i = 0; i < 10; i++)
	{
		printf("a[%d]=%x\n", i,b[i] );
	}
	return 0;
}

3.memmove函数

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main13_03()//memmove()内存移动
{
	int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int b[10];
	memmove(b, a, 40);//将a内存中的值拷贝到b中40个字节大小
	for (int i = 0; i < 10; i++)
	{
		printf("a[%d]=%d\n", i, a[i]);
		printf("b[%d]=%d\n", i, b[i]);
	}
	return 0;
}

4.内存的4个分区以及各个区存放的内容

Code Area

代码区

程序代码指令、常量字符串,只可读

Static Area

静态区

存放全局变量/常量、静态变量/常量

Heap

堆区

由程序员控制,使用malloc/free来操作

Stack

栈区

预先设定大小,自动分配与释放

5.static静态变量

#include<stdio.h>
#include<stdlib.h>

static int a = 2;//文件作用域
//静态全局变量只能在定义它的文件内部访问,在文件外部其他文件不可使用
int main0201()
{
	int a = 0;//函数作用域
	{
		int a = 1;//代码块作用域
		printf("a=%d\n", a);
	}
	printf("a=%d\n", a);
	return 0;
}

//static int a=0;//定义了一个静态变量
void test()
{
	static int a = 0;//static 值只初始化一次
	a++;
	printf("a=%d\n", a);
}
int main0202()
{
	register int a = 0;
	static int b = 0;//静态变量
	for(int i=0;i<10;i++)
	test();
	return 0;
} 

//static void test1()
//静态函数只能在这个文件内部使用,其他文件无法调用,声明也不可调用
 void test1()
{
	a++;
}

6.堆区的分配和释放

6.1malloc函数

void * malloc(size_t _Size);

malloc函数在堆中分配参数_Size指定大小的内存,单位:字节,函数返回void*指针。

6.2free函数

void free(void *p);

free负责在堆中释放malloc分配的内存。参数p为malloc返回的堆中内存地址。

6.3calloc函数

void *calloc (size_t _Count,size_t _Size);

calloc() 与malloc()的一个重要区别是:calloc() 在动态分配完内存后,自动初始化该内存空间为零,而 malloc() 不初始化,里边数据是未知的垃圾数据。

下面分配10个int的两种方式:

1.	//calloc()分配内存空间并初始化
2.	char*str1=(char*)calloc(10,2);
3.	//malloc()分配内存空间并用memset()初始化
4.	char*str2=(char    *)malloc(20);
5.	memset(str2,0,20);

但:malloc只分配不清空,calloc分配完内存的同时将每个字节初始化为0。

7.realloc

重新分配用malloc或者calloc函数在队中分配内存空间的大小。

void*realloc(void*p,size_t _NewSize);

参数一p为之前用malloc或者calloc分配的内存地址,_Newsize为重新分配内存的大小,单位:字节。

	int*p=malloc(200);
	p=realloc(p,400);//在p的基础上,将堆内存扩展到400字节
	p=realloc(p,100);//在p的基础上,将堆内存缩小到100字节
	int*p1=realloc(NULL,100);//如果参数1是NULL,那么realloc作用与malloc一致


8.结构体初始化

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
struct student
{
	char name[100];
	int age;
};

int main0101()
{
	struct student st;//定义了一个student类型的结构体变量,名叫st
	st.age = 20;
	strcpy(st.name, "刘德华");
	printf("name=%s\nage=%d\n", st.name, st.age);
	return 0;
}
//定义结构体的几种方式
int main0102()
{
	//struct student st = { "周星驰",40 };//定义结构体变量时同时初始化成员变量
	//struct student st = { "周杰伦" };
	//struct student st = { 0 };
	struct student st = { .age = 30,.name = "张学友" };
	printf("name=%s\nage=%d\n", st.name, st.age);
	return 0;
}

9.结构体对齐方式

struct A
{
	int a1;
	char a2;
	char a3;
	char a4;
	char a5;
	char a6;
};
//结构体的大小以最大类型变量为对齐单位,如char、int同时存在以int为单位
int main0103()
{
	struct A a;
	printf("%u\n", sizeof(a));
	return 0;
}

/*
char、short、int三种类型在内存中的存放顺序
char 与short中间空闲一个字节空间,即第二个字节空闲
short 、char、int
这种情况short与char挨着,第四个字节空闲

故对齐时总在以2的倍数位置对齐
 */
struct B//12个字节大小
{
	char a1;
	short a2;
	char a4;
	int a3;
};
struct C//8字节大小
{
	char a1;
	char a4;
	short a2;
	int a3;
};

int main0104()
{
	struct C a = { 1,2,3 };
	printf("%u\n", sizeof(a));
	//printf("%p\n", &a);
	return 0;
}

/*结构体中出现数组时
以数组每个成员作为对齐标准,即char[0]与int、char[1]与int比;
若所有成员均为同一种类型
那么结构体变量在内存中基本与一个数组类似*/

struct D//以int为对齐单位
{
	char a[10];
	int b;
};
struct E//给 char 与 short 空闲的一个字节使用指针利用起来赋值
{
	char a1;
	short a2;
	int a3;
};
struct F
{
	char a1;
	short a2;
	int a3;
	short a4;
	char a5;
};
int main0105()
{
	struct D d = { 0 };
	printf("%u\n" , sizeof(d));
	char* s = (char*)&d;
	s[0] = 'a';
	s[1] = 'b';
	s[10] = 'c';
	printf("%s\n", d.a);
	printf("%p,%p\n", &d, d.a);//结构体变量地址即结构体首元素地址

	struct E e = { 1,2,3 };
	s = &e;
	s[1] = 10;//在char和short中写入10
	printf("%p\n", &e);
	return 0;
}

10.结构体元素位字段

定义一个结构体的时候可以指定具体元素的位长。

struct    test        
{        	         
  	char  a:  2;//指定元素位长为2,即2bit        
} 

11.结构体数组

struct man m[10]={{"tom",12},{"marry",10},{"jake",9}};

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>

struct student
{
	char name[20];
	unsigned char age;
	int sex;
};

//给结构体成员按照年龄从小到打排序
void swap_str(char* a, char* b)//结构体成员名字互换
{
	char temp[20] = { 0 };
	strcpy(temp, a);
	strcpy(a, b);
	strcpy(b, temp);
}
void swap_int(int* a, int* b)//年龄、性别互换
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

int mai0301n()
{
	//定义一个结构体数组,共3个成员,每个成员都是struct student

	//struct student st[3] = { {"刘德华",30,1},{"XRB",25,0},{"cls",50,0} };
	//struct student st[3] = { {"刘德华",30,1},{"XRB",25,0} };
	struct student st[] = { {"刘德华",30,1},{"XRB",25,0},{"cls",50,0} ,{"AO8MA",45,1} };

	//for (int i = 0; i < 3; i++)
	//{
	//printf("please input name:");
	//scanf("%s", st[i].name);
	//printf("please input age:");
	//scanf("%d", &st[i].age);
	//printf("please input sex:");
	//scanf("%d", &st[i].sex);
	//}

	for (int i = 0; i < sizeof(st) / sizeof(st[0]); i++)//为结构体成员按照年龄从小到大排序
	{
		for (int j = 0; j < sizeof(st) / sizeof(st[0])-1 - i; j++)
		{
			if (st[j].age > st[j + 1].age)
			{
				swap_str(st[j].name, st[j + 1].name);
				swap_int(&st[j].age, &st[j + 1].age);
				swap_int(&st[j].sex, &st[j + 1].sex);

			}
		}
	}
	for (int i = 0; i < sizeof(st)/sizeof(st[0]); i++)
	{
		if (st[i].sex == 1)
		{

			printf("%s,%d,男\n", st[i].name, st[i].age, st[i].sex);
		}
		else
		{
			printf("%s,%d,女\n", st[i].name, st[i].age, st[i].sex);

		}
	}
	return 0;

}

12.结构体的嵌套

结构体可以嵌套结构体。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>

//结构体的嵌套
struct A
{
	char a1;
};

struct B
{
	struct A a;
	char a2;
	int a1;
};

struct C
{
	struct B;
};
int main0401()
{
	struct B b;
	printf("%u\n", sizeof(b));
	return 0;
}
struct D
{
	char a;
};

struct A1
{
	int a1;
	char a2;
};
struct A2
{
	struct A1 a1;//结构体嵌套A1的结构体变量作为整体存在,不会将A2在内存中补到A1中
	char a2;
	int a3;
};
int main0402()
{
	printf("%u\n", sizeof(struct A2));
	return 0;
}

13结构体的赋值

struct student
{
	char name[20];
	int age;
};
int main0403()
{
	struct student st1 = { "abc",30 };
	struct student st2;
	st2 = st1;//结构体赋值,赋值就是内存的拷贝
	//memcpy(&st2, &st1, sizeof(st1));//同上
	printf("%s,%d\n", st2.name, st2.age);


	//指向结构体的指针
	struct student* p;
	p = &st1;
	//strcpy((*p).name, "hello");
	//(*p).age = 50;

	strcpy(p->name, "hello");
	p->age = 50;
	printf("%s,%d\n", st1.name, st1.age);
	return 0;
}

14.指向结构体数组的指针


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>


struct student
{
	char name[20];
	int age;
};
int main0501()
{
	struct student st[3] = { {"张三",40},{"李四",42},{"涨涨",50} };
	struct student* p = st;
	p->age = 100;
	p++;
	p->age = 20;
	p--;
	for (int i = 0; i < 3; i++)
	{
		printf("%s,%d\n", p[i].name, p[i].age);
	}
}




struct man
{
	char *name[20];
	int age;
};

int main()
{
	struct student st = {0};
	strcpy(st.name, "刘德华"); 
	st.age = 30;
	printf("%s,%d\n", st.name, st.age);
	struct man m = {0};//此时m中的name是空指针
	m.name = calloc(20,sizeof(char));
	strcpy(m.name, "张学友");
	m.age = 40;
	printf("%s,%d\n", m.name, m.age);
	return 0;
}
//c语言结构体的浅拷贝和深拷贝

相关推荐

“版本末期”了?下周平衡补丁!国服最强5套牌!上分首选

明天,酒馆战棋就将迎来大更新,也聊了很多天战棋相关的内容了,趁此机会,给兄弟们穿插一篇构筑模式的卡组推荐!老规矩,我们先来看10职业胜率。目前10职业胜率排名与一周前基本类似,没有太多的变化。平衡补丁...

VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符&quot;

首先,程序中头文件的选择,要选择头文件,在文件中是没有对M_PI的定义的。选择:项目——>”XXX属性"——>配置属性——>C/C++——>预处理器——>预处理器定义,...

东营交警实名曝光一批酒驾人员名单 88人受处罚

齐鲁网·闪电新闻5月24日讯酒后驾驶是对自己和他人生命安全极不负责的行为,为守护大家的平安出行路,东营交警一直将酒驾作为重点打击对象。5月23日,东营交警公布最新一批饮酒、醉酒名单。对以下驾驶人醉酒...

Qt界面——搭配QCustomPlot(qt platform)

这是我第一个使用QCustomPlot控件的上位机,通过串口精确的5ms发送一次数据,再将读取的数据绘制到图表中。界面方面,尝试卡片式设计,外加QSS简单的配了个色。QCustomPlot官网:Qt...

大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写

老友相聚,仗剑江湖!《大话西游2》2021全民PK季4月激燃打响,各PK玩法鏖战齐开,零门槛参与热情高涨。PK季期间,不仅各种玩法奖励丰厚,参与PK趣闻录活动,投稿自己在PK季遇到的趣事,还有机会带走...

测试谷歌VS Code AI 编程插件 Gemini Code Assist

用ClaudeSonnet3.7的天气测试编码,让谷歌VSCodeAI编程插件GeminiCodeAssist自动编程。生成的文件在浏览器中的效果如下:(附源代码)VSCode...

顾爷想知道第4.5期 国服便利性到底需优化啥?

前段时间DNF国服推出了名为“阿拉德B计划”的系列改版计划,截至目前我们已经看到了两项实装。不过关于便利性上,国服似乎还有很多路要走。自从顾爷回归DNF以来,几乎每天都在跟我抱怨关于DNF里面各种各样...

掌握Visual Studio项目配置【基础篇】

1.前言VisualStudio是Windows上最常用的C++集成开发环境之一,简称VS。VS功能十分强大,对应的,其配置系统较为复杂。不管是对于初学者还是有一定开发经验的开发者来说,捋清楚VS...

还嫌LED驱动设计套路深?那就来看看这篇文章吧

随着LED在各个领域的不同应用需求,LED驱动电路也在不断进步和发展。本文从LED的特性入手,推导出适合LED的电源驱动类型,再进一步介绍各类LED驱动设计。设计必读:LED四个关键特性特性一:非线...

Visual Studio Community 2022(VS2022)安装图文方法

直接上步骤:1,首先可以下载安装一个VisualStudio安装器,叫做VisualStudioinstaller。这个安装文件很小,很快就安装完成了。2,打开VisualStudioins...

Qt添加MSVC构建套件的方法(qt添加c++11)

前言有些时候,在Windows下因为某些需求需要使用MSVC编译器对程序进行编译,假设我们安装Qt的时候又只是安装了MingW构建套件,那么此时我们该如何给现有的Qt添加一个MSVC构建套件呢?本文以...

Qt为什么站稳c++GUI的top1(qt c)

为什么现在QT越来越成为c++界面编程的第一选择,从事QT编程多年,在这之前做C++界面都是基于MFC。当时为什么会从MFC转到QT?主要原因是MFC开发界面想做得好看一些十分困难,引用第三方基于MF...

qt开发IDE应该选择VS还是qt creator

如果一个公司选择了qt来开发自己的产品,在面临IDE的选择时会出现vs或者qtcreator,选择qt的IDE需要结合产品需求、部署平台、项目定位、程序猿本身和公司战略,因为大的软件产品需要明确IDE...

Qt 5.14.2超详细安装教程,不会来打我

Qt简介Qt(官方发音[kju:t],音同cute)是一个跨平台的C++开库,主要用来开发图形用户界面(GraphicalUserInterface,GUI)程序。Qt是纯C++开...

Cygwin配置与使用(四)——VI字体和颜色的配置

简介:VI的操作模式,基本上VI可以分为三种状态,分别是命令模式(commandmode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下:1)...

取消回复欢迎 发表评论: