1. 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

  1. 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;

}

  1. 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函数,以字节为单位设置

  1. 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类型来创建成员变量时不行的

  1. 结构体的传参:

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

}

注:如果是结构体指针,用指向符->

  1. 结构体内存对齐:

内存对齐是计算机对内存中数据存放位置的一种要求,指向的是数据起始内存地址必须是其自身大小的数倍

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

}

大小计算;

联合体的大小至少是最大成员的大小

当最大成员大小不是最大对齐数的整数倍时,就要找到最大对齐数的整数倍

  1. 枚举类型:

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;

}

}

}

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐