DAY16 Advanced C Programming: `void*`, Structures, Memory Copying, and Alignment

C语言高级编程:结构体与内存对齐

编程达人挑战赛·第4期 10w+人浏览 240人参与

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:

  1. Each member must be placed at an offset that is a multiple of its size
    (e.g., int must align to 4 bytes).
  2. 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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值