C 语言高级指针与结构体:void*、结构体、字节对齐、memcpy
1. void* —— C 语言的“万能指针”
void* 又叫“通用指针”,可以接收任意类型的地址,是很多底层库函数(如 memcpy、qsort)的基础。
1.1 void* 能做什么?
- 可以存储任意指针
- 可以作为函数参数 → 实现泛型效果
- 可以作为函数返回值
- 适合实现通用库函数(如 memcpy)
示例:
int a = 20;
char s[100] = "hello";
void *p = &a;
printf("%d\n", *(int*)p);
p = s;
printf("%s\n", (char*)p);
1.2 void* 不能直接做什么?
- ❌ 不能解引用:
*p(因为不知道类型) - ❌ 不能
p++递增(无类型 → 无步长)
必须 强制转换后 才能使用:
(int*)(p) + 1
(char*)(p) + 1
2. 自定义 memcpy / mystrcpy / myintcpy
为了理解 void* 和内存操作,我们手写了简单的内存拷贝函数。
⭐ 2.1 mystrcpy — 字符串拷贝
char* mystrcpy(char* dst,char* src)
{
char* tmp = dst;
while(*src!='\0')
{
*dst = *src;
dst++;
src++;
}
*dst='\0';
return tmp;
}
2.2 myintcpy — int 数组拷贝
int *myintcpy(int *dst,int *src,int len)
{
int *tmp=dst;
for(int i=0;i<len;i++)
{
*dst=*src;
dst++;
src++;
}
return tmp;
}
⭐ 2.3 mymemcpy(万能 memcpy)
关键代码:
int *mymemcpy(void *dst, void *src, int len)
{
void *tmp = dst;
char *d = (char*)dst;
char *s = (char*)src;
for(int i=0;i<len;i++)
{
*d = *s;
d++;
s++;
}
return tmp;
}
解释:
- 使用
char*进行拷贝,因为char是 1 字节,最适合逐字节复制。 - 这就实现了真正意义上的通用 memcpy。
3. 结构体(struct)基础
3.1 结构体定义
struct date
{
int year;
int month;
int day;
};
3.2 结构体初始化
struct date d1 = {2025, 11, 24}; // 完全初始化
struct date d2 = { // 部分初始化
.year = 2025,
.day = 10
};
未赋值的成员会自动设为 0。
4. 结构体指针与成员访问
结构体变量使用点号访问:
d1.year;
结构体指针使用箭头访问:
struct date *p = &d1;
p->year;
等价于:
(*p).year;
5. 结构体字节对齐(重点)
字节对齐的目的:
提高 CPU 访问内存的效率
对齐规则:
- 每个成员的地址必须是其类型大小的整数倍(如 int 必须对齐到 4 的倍数)
- 结构体总大小 必须是 最大成员类型大小的整数倍
示例代码(来自你今天的实验):
struct per
{
char name[50];
char sex;
int age;
int score;
};
struct per3
{
double a;
char c;
short s;
struct per2 p;
};
输出结构体大小:
printf("sizeof p is %lu\n", sizeof(p));
printf("sizeof p3 is %lu\n", sizeof(p3));
printf("sizeof p4 is %lu\n", sizeof(p4));
通过观察不同类型排列导致的对齐变化,可以深入理解结构体布局规则。
6. 结构体数组与函数传参
结构体数组:
struct PER
{
char name[50];
float heigh;
};
struct PER per[3] =
{
{"zhangsan",1.75},
{"lisi",1.70},
{"wangmazi",1.95},
};
传给函数时应使用指针,提高效率:
void show_array(struct PER* per, int len)
{
for(int i=0;i<len;i++)
printf("%d %s %f\n", i, per[i].name, per[i].heigh);
}
调用:
show_array(per, 3);
7. 综合示例:结构体操作与 mymemcpy
struct person per = {"zhangsan",20,90.5};
struct person per2 = {0};
mymemcpy(&per2, &per, sizeof(per));
printf("%s %d %f\n", per2.name, per2.age, per2.score);
这就实现了结构体的深拷贝。
878

被折叠的 条评论
为什么被折叠?



