Advanced C Programming: void*, Structures, Memory Copying, and Alignment
1. void* — The Universal Pointer in C
A void* pointer (generic pointer) is a pointer that can store the address of any type, making it extremely powerful for writing generic functions.
1.1 What can a void* do?
- Store the address of any variable type
- Serve as a function parameter to support generic programming
- Serve as a function return type
- Be used in low-level library functions (e.g.,
memcpy,qsort)
Example:
int a = 20;
char s[100] = "hello";
void *p = &a;
printf("%d\n", *(int*)p);
p = s;
printf("%s\n", (char*)p);
1.2 What can’t a void* do?
- ❌ Cannot be dereferenced directly (
*p) - ❌ Cannot be incremented with
p++
To use a void*, you must explicitly cast it:
*(int*)p
(char*)p + 1
2. Writing Your Own Memory Functions
To understand pointer arithmetic and memory layouts, we implemented simplified versions of common functions.
2.1 mystrcpy — Copying Strings
char* mystrcpy(char* dst, char* src)
{
char* tmp = dst;
while (*src != '\0')
{
*dst = *src;
dst++;
src++;
}
*dst = '\0';
return tmp;
}
2.2 myintcpy — Copying Integer Arrays
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 — A General-Purpose Memory Copy
This demonstrates why we use void*:
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;
}
By converting void* to char*, we can copy memory byte by byte, just like the actual memcpy implementation.
3. Structures: Definition and Initialization
3.1 Basic structure definition
struct date
{
int year;
int month;
int day;
};
3.2 Full and partial initialization
struct date d1 = {2025, 11, 24}; // full initialization
struct date d2 =
{
.year = 2025,
.day = 10
}; // partial initialization — remaining fields become 0
4. Structure Pointers and Member Access
Dot operator (.) — for structure variables
printf("%d", d1.year);
Arrow operator (->) — for structure pointers
struct date *p = &d1;
printf("%d", p->year);
Equivalent to:
(*p).year
5. Structure Memory Alignment
Memory alignment improves CPU performance by ensuring variables are placed at efficiently accessible addresses.
Alignment rules:
- Each member must be placed at an offset that is a multiple of its size
(e.g.,intmust align to 4 bytes). - The total structure size must be a multiple of the largest member size.
Example:
struct per
{
char name[50];
char sex;
int age;
int score;
};
Measuring sizes:
printf("sizeof p is %lu\n", sizeof(p));
Different member ordering will change the structure’s size due to alignment and padding.
6. Structure Arrays and Passing Them to Functions
Structure array example
struct PER
{
char name[50];
float height;
};
struct PER per[3] =
{
{"zhangsan", 1.75},
{"lisi", 1.70},
{"wangmazi", 1.95},
};
Passing structure arrays by pointer
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].height);
}
}
7. Structure Copying (Deep Copy)
struct person per = {"zhangsan", 20, 90.5};
struct person per2 = {0};
mymemcpy(&per2, &per, sizeof(per));
This creates a complete copy of the structure.
C语言高级编程:结构体与内存对齐
4686

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



