C语言内存函数详解
- memcpy:
语法:
Void*memcpy(void*destination,const void*source,size_t num);
功能:
memcpy是完成内存块拷贝的,不关注内存中存放的数据是啥
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置
如果source和destination有任何的重叠复制结果都是未定义的
用<string.h>的头文件
Int a=10;
Void *p=&a;
Int*p2=(int*)p;
*p2=>10(类型转换必须用括号把目标类型包起来)
注:void*p
不能进行指针运算,强制性转换
为什么要把参数设为void?
Char a=’a’;
Void*p=&a;
Char*pc=(char*)p;(函数内部把当前void*进行转换或集体指针)
演示:
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[] = { 0 };
memcpy(arr2, arr1, 20);// 20/4=5
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d", arr2[1]);
}
return 0;
}//1,2,3,4,5,0,0,0,0,0
内存重叠:
例:
#include<stdio.h>
#include<string.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
memcpy(&arr[2], &arr[0], 5 * sizeof(int));
for (int i = 0; i < 0; i++)
{
printf("%d", arr[i]);
}
return 0;
}
虽然运行结果是正确的,但官方还是认为这种属于未定义行为,建议用memmove
- Memmove
语法:
Void*memmove(void*destination,const void*source,size_t num);
功能:
Memmove也是完成内存拷贝的
和memmove的差别就是memmove函数的原内存块和目标内存块可以重叠
Memmove也要<string.h>
例:
#include<stdio.h>
#include<string.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(&arr[2], &arr[0], 5 * sizeof(int));
for (int i = 0; i < 0; i++)
{
printf("%d", arr[i]);
}
return 0;
}
- Memset
Void*memset(void*ptr,intvalue,size_t num);
功能:
Memset函数是用来设置内存条的内容的,将内存中指定长度的空间设置为特定的内容
3.1代码演示:
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "hello world";
memset(str, 'x', 6);
printf(str);
return 0;
}//xxxxxworld
注:
当有一块内存空间需要设置内容时,就可以用memset函数,以字节为单位设置
- Memcmp
Int memcmp(const void*ptr1,const void8ptr2,size_t num);
功能:
比较指定两块内存的内容,比较从ptr1和ptr2开始,向后num个字节
例:
#include<stdio.h>
#include<string.h>
int main()
{
char buffer1[] = "DWgaOtP12dfo";
char buffer2[] = "DWGAOTP12DFO";
int n;
n = memcmp(buffer1, buffer2, sizeof(buffer1));
}
C语言结构体:
1.定义:
结构体是一种用户自定义的复合类型,允许将多个不同类型的数据组合成一个逻辑相关的数据单元,可以将结构体看作是一个包含了一组变量的集合,这些变量被称为结构的成员或字段
1.1结构的声明:
语法结构:
Struct tag
{
Member_list;//成员列表
}variable_list;//变量列表
例:
#include<stdio.h>
#include<string.h>
struct student
{
char name[10];
int age;
char sex[5];
char id[20];
}s1,s2,s3;
int main()
{
struct student stu1 = { "zhangsan",10,"man","20260115" };
struct student stu2 = { "lisi",20,"man","20260116" };
printf("name:%s\n", stu1.name);
printf("age:%d\n", stu1.age);
printf("name:%s\n", stu2.name);
printf("age:%d\n", stu2.name);
}
注:
进行赋值时要有顺序(结构体中的顺序)
最后哪怕没有变量列表也要加‘;’
访问:结构体变量+点号的方式来访问对应的结构体当中的数据
虽然里面成员变量一样但不是2个一样的结构体
1.4结构体的自引用:
在结构体中包含一个类型为该类型本身的成研是否可以?
例:
struct Node
{
int data;
struct Node next;
};
注:
自引用可以把一个节点指向另一个同类型节点,把零散节点串起来
1.4.1 typedef:
在结构体自引用时,夹杂了typedef对匿名结构体类型重命名,也容易引入问题
例
typedef long long int LLint;
int main()
{
long long int a;
LLint b = 20;
return 0;
}
注:
在匿名结构体内部提前使用node类型来创建成员变量时不行的
- 结构体的传参:
typedef struct stu
{
char name[10];
int age;
char sex[5];
char id[20];
}stu;
void print_struct1(stu s)
{
printf("%s\n", s.name);
printf("%d\n", s.age);
printf("%s\n", s.sex);
printf("%s\n", s.id);
}
注:如果是结构体变量用点号
void print_struct1(stu* ps)
{
printf("%s\n", (* ps).name);
printf("%d\n", (* ps).age);
printf("%s\n", (* ps).sex);
printf("%s\n", (* ps).id);
printf("%s\n", ps->name);
printf("%d\n", ps->age);
printf("%s\n", ps->sex);
printf("%s\n", ps->id);
}
注:如果是结构体指针,用指向符->
- 结构体内存对齐:
内存对齐是计算机对内存中数据存放位置的一种要求,指向的是数据起始内存地址必须是其自身大小的数倍
3.对其规则:
1.结构体的第1个成员对齐到和结构体变量起始位置偏移量为0的地址处。
2. 从第2个成员变量开始,都要对齐到某个对齐数的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数 与 该成员变量大小的较小值。 VS 中默认的值为 8 Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小
3. 结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最 大对齐数(含嵌套结构体中成员的对齐数)的整数倍。
struct s4
{
char c1;//8
struct s3;//16
double d;//8
};
3.2修改默认对齐数:
#pragma这个预处理指令,可以改变编译器的默认对齐数
例:
#pragma pack(1)//默认对齐数为1
struct s
{
char c1;
int i;
char c2;
};
#pragma pack()//取消设置对齐数,还原默认
int main()
{
printf("%d\n", sizeof(struct s));
return 0;
}联合体&枚举类型:
- 联合体:
1.1联合体的声明:
联合体也是有一个或者多个成员构成,这些成员可以是不同的类型,但是编译器只为最大的成员分配足够的内存空间
联合体的特点是所有成员共用一块内存空间,所以联合体也叫做:共用体
例:union UN
{
char c;
int i;
};
int main()
{
//定义联合变量
union UN un = { 0 };
un.c = 'a';
un.i = '10';
//计算联合体变量的大小
pribtf("%d\n,sizeof(un)");
return 0;
}
大小计算;
联合体的大小至少是最大成员的大小
当最大成员大小不是最大对齐数的整数倍时,就要找到最大对齐数的整数倍
- 枚举类型:
2.1枚举的声明与特定
不是都可以用枚举进行表示,相反一些不是有限集合的就不可能用枚举表示
例:
enum day//星期
{
mon=1,//手动赋值依次补充
tues,
thu,
//...
};
例:
enum trafficlight
{
red,//默认为0
green,//1
yello//2
};
int main()
{
enum trafficlight light= red;//初次为红灯
//模拟三次变化
for (int i = 0; i < 3; i++)
{
switch (light)
{
case red:
printf("红灯停\n");
light = green;//红变绿
break;
case green:
printf("绿灯行\n");
light = yello;//红变绿
break;
case yello:
printf("黄灯等一等\n");
light = red;//红变绿
break;
}
}
}
更多推荐

所有评论(0)