zoukankan      html  css  js  c++  java
  • c语言,结构体

    数据类型分为4种, 简单数据类型,构造数据类型,指针数据类型,空类型。

    结构体属于构造数据类型,用struct标识。

    声明一个结构体:

    Typedef  struct和struct

    c

    c++

    typedef struct tMyStruct

    {

    int iNum;

    long lLength;

    } ST_MYSTRUCT;

    在C中,这个申明后申请结构变量的方法有两种:

    (1)struct tMyStruct 变量名;;

    2ST_MYSTRUCT变量名

    在c++中可以有

    (1)struct tMyStruct 变量名;

    2ST_MYSTRUCT变量名

    (3)tMyStruct 变量名;

    typedef struct

    {

    int a;

    }ST_MYSTRUCT;

    在声明变量的时候就可:

    ST_MYSTRUCT  st1;

    typedef struct

    {

    int a;

    }ST_MYSTRUCT,ST_MYSTRUCT_PTR;

    定义了结构体类型ST_MYSTRUCT

    以及结构体指针类型ST_MYSTRUCT_PTR

     

    typedef struct  

    {

    int num;

    int age;

    }ST_AAA,ST_BBB,ST_CCC;

    ST_AAA,ST_BBB,ST_CCC三者都是同一结构体类型。声明变量时用任何一个都可以,c++中也是如此

    同左。

    struct Student {

    int a ;

    }stu1;        

    声明了结构体类型struct Student

    同时也声明了结构体变量stu1

    struct {

    int a ;

    }stu1;        

    声明了结构体变量stu1

     

    • 结构体赋值:

    struct st1 {
        int a;
        int b;
    };
    
    1 对成员赋值.
    1.1 用{}形式.
    struct st1 st1 = {1,2,3);    //定义并初始化结构体变量
    1.2 linux kernel风格.
    struct st1 st1 = {    //定义并初始化结构体变量
    .a = 1;
    .b = 2;
    };
    
    2 对整体赋值.
    struct st1  a, b;    //声明结构体变量
    b = a;    //结构体直接赋值
    
    3 结构体作为函数返回值对另一个结构体赋值.
    struct st1 func1();
    
    struct st1 a = func1();

      

    • 结构体直接赋值的不安全因素:(c语言)

    struct A{
      char v1[20];
      int v2;
    } a,b;

    a = b;
    这没有任何问题.

    但是:
    struct B{
      char *v1;
      int v2;
    } c,d;
    c = d;
    这种结构体赋值,就需要注意(包括在C++里)。
    对于指针赋值,即不是数据进行了复制保存而是多了一个指针指向而已,这样一旦b对象释放,a的指向就成了非法的垃圾数据。

    所以在c中,自定义类型、数组都是要另外自己定义复制函数的,这主要是代码安全考虑,而不是语言层面考虑。

    • 结构体定义,声明,赋值:

    #include <stdio.h>
    //也可以这样:
    typedef struct st1 {
        int e1;
        int e2;
    }ST_MY; //1.定义结构体类型的时候,里面是分号,定义完毕后要加分号。
    
    ST_MY func1()
    {
        ST_MY h = { 77, 88};
        return h;
    }
    
    int main()
    {
        ST_MY a = { 33, 44}; // 2.定义并初始化一个结构体
        ST_MY b = {
            .e1 = 55, //3.0 定义并初始化一个结构体时,可以点赋值
        }; //3.1 点赋值只能是初始化结构体变量时才能用
        ST_MY c;
        ST_MY d, e;
        
        c = a;//4.结构体直接赋值(方法1)
        d = func1();//5.结构体直接赋值(方法2)
        e.e2=77; //6.声明之后为一个结构体变量赋值效果.不同于定义并初始化一个结构体变量。
        
        printf("a.e1 a.e2 is %d %d
    ", a.e1, a.e2);
        printf("b.e1 b.e2 is %d %d
    ", b.e1, b.e2);
        printf("c.e1 c.e2 is %d %d
    ", c.e1, c.e2);
        printf("d.e1 d.e2 is %d %d
    ", d.e1, d.e2);
        printf("e.e1 e.e2 is %d %d
    ", e.e1, e.e2);
        
        f1();
        
        return 0;
    }
    /*
    root@oucaijun:/work/dcc# gcc *.c; ./a.out
    a.e1 a.e2 is 33 44
    b.e1 b.e2 is 55 0
    c.e1 c.e2 is 33 44
    d.e1 d.e2 is 77 88
    e.e1 e.e2 is -1074143256 77    //6.声明之后为一个结构体变量赋值效果.不同于定义并初始化一个结构体变量。
    */

      

    •  结构体与数组比较

    结构体是一等公民;

    数组是二等公民

    从词条上解释可以看出二等公民与一等公民在权利上是有差别的,这个词很有意思作为计算机专业术语,其含义也有异曲同工之妙!同样我们看看维基百科对计算机的术语”first-class citizen"(一等公民)的定义,一般要满足以下几点,

        • can be stored in variables and data structures
        • can be passed as a parameter to a subroutine
        • can be returned as the result of a subroutine
        • can be constructed at run-time
        • has intrinsic identity (independent of any given name)

    对比着上面的定义来看C语言数组,

    数组作为一个函数的参数传递时,退化成一个指针;

    同时,数组无法作为函数的返回值;

    也许让数组更不服气的是,数组之间不能直接赋值操作,

    如下面的操作就是非法的:

    int a[10];
    int b[10];
    a = b;

    但是如果数组包装在结构体中,那么就能进行赋值了!

    相比之下,结构体可以作为函数参数和返回值,这就是一等公民的待遇!

    至于为什么数组必须是二等公民,这是有历史原因的,大家可以参考C 语言的发展史来看,有时间这块内容我再补上!

    源文档 <http://www.cnblogs.com/hazir/p/C_struct_assignment.html>

  • 相关阅读:
    Github开始强制使用PAT(Personal Access Token)了
    STM32F401的外部中断EXTI
    STM32F401的PWM输出
    STM32F103和STM32F401的ADC多通道采集DMA输出
    nRF24L01无线模块笔记
    51单片机(STC89C52)在Ubuntu下的开发
    51单片机(STC89C52)的中断和定时器
    51单片机的软件和硬件PCA/PWM输出
    Zadig 云原生持续交付 面向开发者设计的开源、高可用 CI/CD
    人生 乐观 悲观 英雄
  • 原文地址:https://www.cnblogs.com/mylinux/p/4667991.html
Copyright © 2011-2022 走看看