C中的结构体与联合体异同

联合体

       C语言的联合体union又叫做共用体,并不常用,类似于大家所熟知的结构体struct。如其名,我们差不多能获知这个数据结构有一部分东西是共用的,结构里面除了变量空间,也没什么可以共用的了。即,共用体内部所有声明的变量,均为共用一个内存首址,联合体占用内存大小与联合体内部占用空间最大的变量相同。我们给其中每一个变量进行的赋值,都会影响到其他变量的值。下面直接砍一刀关于联合体的选择题。

#include stdio.h;
int main()
{
    union
    {
        short int a[2];
        long b;
        char c[4];
    }s;
    s.a[0]=0x39;
    s.a[1]=0x38;
    printf("%lx %c\n",s.b,s.c[0]);

}

       所以上面那道题的输出结果是?

       3839 39?不对。

       380039 39?不对。

       答案是: 380039 9。 有点懵。

       现在开始分析一下这道题,意图很明显,要考察联合体以及printf输出的格式符两个点。

       short int 每个占两字节,两个四字节;long 占四字节;char 每个占一字节,四个占四字节。因此这三个变量所占据的内存空间大小一致,画了个草图如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ECcqoDNX-1605776793059)(http://i.imgur.com/JbpHnqx.png)]

       因此在对s.a进行赋值之后,联合体内部数据使用16进制表示为:

0x 0038 0039。而此时还应该注意的是char c[0]中存的是0x39,打印的是%c,即字符,所以打印出的字符不是0x39,而是0x39指向的ASCII码,即0x39=57,57对应字符9。所以,这道题打印出的结果是:

380039 9 。

结构体

       关于C的结构体,我觉得我理解的还是不够深入,直接看一道题。

#include <stdio.h>
#include <string.h>
 struct A
 {
    int a;
    char b [10];double c;
    };
    void f(struct A t);
    int main()
    {
    struct A a={1001,"zhang",1908};
    f(a);
    printf("%d,%s,%6.1f\n",a.a,a.b,a.c);
    return 1;
    }
void f(struct A t)
{   
t.a=1002;strcpy(t.b,"chang");  
t.c=1201;  
}

       进行过这样一番操作之后,结构体A的内容并没有变化,输出的结果与之前相同。这就让我当时觉得很费解的一个问题,为什么我传递进去结构体,而且修改了值,却实际内容没有变化?

       其实,我在这里陷入了一个僵化的思维,在学习c之后,我接触了java,这段代码中的结构体,在java里面被视为内部类的存在,而A a相当于面向对象新建的对象,若是在java里面,对象作为函数的实参,此时传递的相当于对象的指针,指针在java中简化了。这样,函数中对形参对象的任何改变都会与实参同步改变。但需要注意的是,这里不是java,struct也不是对象。c语言中struct作为函数形参时,依旧是作为实参的一个副本,副本在子函数中再怎么改变,只要不return值,就不会影响到实参的值。

指针的形参实参

       这样根据上个题,就会想到通过函数参数传递,进行两个数交换的demo。使用的原理就是函数参数为指针,对两个指针中的数据内容进行交换,从而达到交换实参中的数据的目的。

正确的例子

  void fun(int *p,int *q)
    {
        int a;
        a = *p;
        *p = *q;
        *q = a;
    }

错误的例子

void fun(int *p,int *q)
    {
        int *a;
        a = p;
        p = q;
        q = a;
    }

       要注意的是,形参始终只是实参的一个副本,形参本身的变化,无法对实参的值造成影响。指针类型的形参与实参虽然不是一个变量, 但指向同一个地址;第一个函数,对形参指向的地址进行了数值变化;第二个函数,只是对形参的指向作了修改。

结语

       这些相关的题和知识都是计算机二级的很基础的计算机知识,到现在还需要重新复习一遍。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值