C语言用结构体给另一个同类型结构体赋值: 用等号即可

看到很多C代码的结构体赋值都是用memcpy函数来拷贝,其实根本不需要,用等号直接赋值即可。结构体描述的是的一块连续内存的内存布局,同类型的一个结构体变量给另一个结构体变量赋值,使用等号编译不会有任何问题,其效果显然也和人直觉认为的一样,拷贝对应内存。

通过反汇编看编译器的行为,效果跟memcpy一样,还省掉了函数调用开销,代码更加的简洁明了。

// @file: main.c
struct node {
    long a;
    int  b;
    char c;
    long array[3];
}; 
int main() {
    struct node n1;
    n1.a = 1;
    n1.b = 2;
    n1.c = 3;
    n1.array[0] = 10;
    n1.array[1] = 11;
    n1.array[2] = 12;
    struct node n2 = n1;
    return 0;
}

运行查看其行为:

(gdb)Breakpoint 1, main () at main.c:17
        17      return 0;
(gdb) p n1
$1 = {a = 1, b = 2, c = 3 '\003', array = {10, 11, 12}}
(gdb) p n2
$2 = {a = 1, b = 2, c = 3 '\003', array = {10, 11, 12}}
(gdb) p &n1
$3 = (struct node *) 0x7fffffffe2d0
(gdb) p &n2
$4 = (struct node *) 0x7fffffffe300
(gdb) p sizeof(n1)
$5 = 40
(gdb) p $rbp
$6 = (void *) 0x7fffffffe330
(gdb) disass
Dump of assembler code for function main:
   0x000055555555466a <+0>:     push   %rbp
   0x000055555555466b <+1>:     mov    %rsp,%rbp
   0x000055555555466e <+4>:     sub    $0x60,%rsp
   0x0000555555554672 <+8>:     mov    %fs:0x28,%rax
   0x000055555555467b <+17>:    mov    %rax,-0x8(%rbp)
   0x000055555555467f <+21>:    xor    %eax,%eax
   0x0000555555554681 <+23>:    movq   $0x1,-0x60(%rbp) // &n1 0x..2d0
   0x0000555555554689 <+31>:    movl   $0x2,-0x58(%rbp)
   0x0000555555554690 <+38>:    movb   $0x3,-0x54(%rbp)
   0x0000555555554694 <+42>:    movq   $0xa,-0x50(%rbp)
   0x000055555555469c <+50>:    movq   $0xb,-0x48(%rbp)
   0x00005555555546a4 <+58>:    movq   $0xc,-0x40(%rbp) // n1.array[2] = 12;
   0x00005555555546ac <+66>:    mov    -0x60(%rbp),%rax
   0x00005555555546b0 <+70>:    mov    -0x58(%rbp),%rdx
   0x00005555555546b4 <+74>:    mov    %rax,-0x30(%rbp) // &n2 0x..300
   0x00005555555546b8 <+78>:    mov    %rdx,-0x28(%rbp)
   0x00005555555546bc <+82>:    mov    -0x50(%rbp),%rax
   0x00005555555546c0 <+86>:    mov    -0x48(%rbp),%rdx
   0x00005555555546c4 <+90>:    mov    %rax,-0x20(%rbp)
   0x00005555555546c8 <+94>:    mov    %rdx,-0x18(%rbp)
   0x00005555555546cc <+98>:    mov    -0x40(%rbp),%rax
   0x00005555555546d0 <+102>:   mov    %rax,-0x10(%rbp)
=> 0x00005555555546d4 <+106>:   mov    $0x0,%eax
   0x00005555555546d9 <+111>:   mov    -0x8(%rbp),%rdx
   0x00005555555546dd <+115>:   xor    %fs:0x28,%rdx
   0x00005555555546e6 <+124>:   je     0x5555555546ed <main+131>
   0x00005555555546e8 <+126>:   callq  0x555555554540 <__stack_chk_fail@plt>
   0x00005555555546ed <+131>:   leaveq
   0x00005555555546ee <+132>:   retq
End of assembler dump.
*/

而对于结构体的比较,是要具体到基本数据类型的结构体成员比较,因为有字节对齐,用memcmp是不可靠。除非结构体显示声明单字节对齐,如用__attribute__((packed))修饰了结构体定义。

补充两个资料:
C Programming Resource Center
C99 Standard

  • 26
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
<br /> <input type="submit" value="保存" /> </form> </body> </html> ``` 8. 配置web.xml 在WebContent/WEB-INF目录下创建web.xml文件,添加以下内容: ```xml <?xml version可以使用结构体赋值运算符(=)将一个结构体变量的值赋给另一个相同="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance类型结构体变量。 例如,假设我们有以下的结构体类型: ```c typedef struct { int" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns x; int y; } Point; ``` 然后我们定义了两个 Point 类型的变量 p1 和 p2/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> ,可以通过以下方式将 p1 赋值给 p2: ```c Point p1 = {1, 2}; Point p <display-name>bookstore</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </2; p2 = p1; // 使用赋值运算符将 p1 的值赋给 p2 ``` 这样welcome-file-list> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org,p2 中的 x 和 y 的值就与 p1 中的相同了。注意,这里的赋值是将.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> 整个结构体的值进行复制,而不是把指针进行复制,所以它们是两个独 <param-value>classpath:applicationContext.xml,classpath:spring-mvc.xml</param-value> </init-param> </s立的变量,修改一个变量的值不会影响另一个变量的值。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值