About the problem of struct structure assignment

About the problem of struct structure assignment

1: Shallow copy

The abstract data structure instance of the struct structure can be directly assigned, see this example:

#include <stdio.h>
#include <string.h>
typedef struct con{
    int a;
    int b;
    char c;
    double d;
}Con;
int main(){
    Con a, b;
    a.a = 1;
    a.b = 2;
    a.c = '3';
    a.d = 5.0;

    // assignment
    b = a;
    printf("%d %d %c %f\n", b.a, b.b, b.c, b.d);
    return 0;
}

Operation result:
1 2 3 5.000000

Amazing right? Here is an even more amazing thing:

#include <stdio.h>
#include <string.h>
typedef struct con{
    int a;
    char string[100];
}Con;
int main(){
    Con a, b;
    a.a = 1;
    scanf("%s", a.string);
    // assignment
    b = a;
    printf("%d %s\n", b.a, b.string);
    return 0;
}

Operation result:
hellll
1 hellllo

Even structures nested with structures can also be assigned directly:

#include <stdio.h>
#include <string.h>
typedef struct man{
    int age;
    char name[100];
}Man;
typedef struct con{
    int a;
    char string[100];
    Man man;
}Con;
int main(){
    Con a, b;
    a.man.age = 100;
    scanf("%s", a.man.name);
    a.a = 1;
    scanf("%s", a.string);
    b = a;

    // assignment
    b = a;
    a.man.age = 1000000;
    printf("%d %s %d %s\n", b.a, b.string, b.man.age, b.man.name);
    return 0;
}

Operation result:
Tony
helllooooooooooooo
1 helllooooooooooooo 100 Tony

I suspect that this kind of copy is just a shallow copy, then I did this experiment:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct MyStruct {
    int a;
    int b;
    char* c;
};
int main() {
    struct MyStruct t1;
    t1.a = 1;
    t1.b = 2;
    char* p = (char*)malloc(10 * sizeof(char));
    strcpy(p, "hello");
    t1.c = p;
    struct MyStruct t2;
    t2 = t1;
    printf("MyStruct t1: %d, %d, %s\n", t1.a, t1.b, t1.c);
    // Change the value of t1 at this time to see if t2 is affected
    // *(t1.c) = 'p';
    printf("MyStruct t2: %d, %d, %s\n", t2.a, t2.b, t2.c);
    printf("t1 pointer addr: %p\n", t1.c);
    printf("t2 pointer addr: %p\n", t2.c);
    return 0;
}

Operation result:
MyStruct t1: 1, 2, hello
MyStruct t2: 1, 2, hello
t1 pointer addr: 0x125e06760
t2 pointer addr: 0x125e06760

If *(t1.c) = 'p'; is not commented, it will be like this:

MyStruct t1: 1, 2, hello
MyStruct t2: 1, 2, pello
t1 pointer addr: 0x126606760
t2 pointer addr: 0x126606760

Obviously, t1 and t2 point to the same memory unit. At this time, if the content pointed to by t1 is changed, t2 will change accordingly. Therefore, this copy is just a simple assignment of the literal value, so this copy is a shallow copy .

2: The benefits of shallow copy

I came across this topic on PTA today:
7-1 通讯录排序:

输入格式:
输入第一行给出正整数n(<10)。随后n行,每行按照“姓名 生日 电话号码”的格式给出一位朋友的信息,其中“姓名”是长度不超过10的英文字母组成的字符串,“生日”是yyyymmdd格式的日期,“电话号码”是不超过17位的数字及+、-组成的字符串。

输出格式:
按照年龄从大到小输出朋友的信息,格式同输出。

  • 输入样例:
    3
    zhang 19850403 13912345678
    wang 19821020 +86-0571-88018448
    qian 19840619 13609876543
  • 输出样例:
    wang 19821020 +86-0571-88018448
    qian 19840619 13609876543
    zhang 19850403 13912345678

Code size would be a disaster if there were no shallow copies of C structs in the world, like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct info{
    char name[20];
    int birth;
    char tel[100];
}Info;
int main(){
    int n = 0;
    scanf("%d", &n);
    Info *list = (Info*)malloc(sizeof(Info)*n);
    for(int i = 0; i < n; i++){
        scanf("%s %d %s", list[i].name, &list[i].birth, list[i].tel);
    }
    // 排序
    for(int i = 0; i < n-1; i++){
        for(int j = i+1; j < n; j++){
            if(list[i].birth > list[j].birth){
                Info temp;
               strcpy(temp.name, list[i].name);
                temp.birth = list[i].birth;
                strcpy(temp.tel, list[i].tel);
                
                strcpy(list[i].name, list[j].name);
                list[i].birth = list[j].birth;
                strcpy(list[i].tel , list[j].tel);
                
                strcpy(list[j].name, temp.name);
                list[j].birth = temp.birth;
                strcpy(list[j].tel, temp.tel);
            }
        }
    }
    for(int i = 0; i < n; i++){
        printf("%s %d %s\n", list[i].name, list[i].birth, list[i].tel);
    }
    
    return 0;
}

And the shallow copy of the structure can simply let our code like this:

#include <stdio.h>
#include <stdlib.h>
typedef struct info {
    char name[20];
    int birth;
    char tel[100];
} Info;
int main() {
    int n = 0;
    scanf("%d", &n);
    Info* list = (Info*)malloc(sizeof(Info) * n);
    for (int i = 0; i < n; i++) {
        scanf("%s %d %s", list[i].name, &list[i].birth, list[i].tel);
    }
    // Sorting
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (list[i].birth > list[j].birth) {
                Info temp = list[i];
                list[i] = list[j];
                list[j] = temp;   
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%s %d %s\n", list[i].name, list[i].birth, list[i].tel);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值