C语言中结构体、变量的作用域和mem函数的使用
liebian365 2024-11-16 23:09 22 浏览 0 评论
1.指针中memset函数
memset主要功能就是将一块内存设置为0,即参数2设置为0
#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函数
#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”: 未声明的标识符"
-
首先,程序中头文件的选择,要选择头文件,在文件中是没有对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)...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- “版本末期”了?下周平衡补丁!国服最强5套牌!上分首选
- VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符"
- 东营交警实名曝光一批酒驾人员名单 88人受处罚
- Qt界面——搭配QCustomPlot(qt platform)
- 大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写
- 测试谷歌VS Code AI 编程插件 Gemini Code Assist
- 顾爷想知道第4.5期 国服便利性到底需优化啥?
- 掌握Visual Studio项目配置【基础篇】
- 还嫌LED驱动设计套路深?那就来看看这篇文章吧
- Visual Studio Community 2022(VS2022)安装图文方法
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)