C/C++中的struct

程序=数据结构+算饭
数据结构在程序设计中非常重要,在此总结一些struct的东西,以备忘

目录

[TOC]来生成目录:

初始化

struct数据有3中初始化方法:顺序,C风格及C++风格的乱序。
(1)顺序
顺序初始化的特点是: 按照成员定义的顺序,从前到后逐个初始化;允许只初始化部分成员;在被初始化的成员之前,不能有未初始化的成员,未显示初始化的自动设为0。

struct User oneUser = {10, "Lucy", "/home/Lucy"}; 

( 2)乱序(C风格)
顺序的缺陷是必须按成员定义的顺序逐个初始化,不能间隔。而乱序的方式则很好的解决了这个问题,因为这种方式是按照成员名进行。
而且gcc不支持后缀名为cpp的文件使用这种方式!!!!(待确认)

struct User oneUser = { 
                        .name = "Lucy",  
                        .id = 10, 
                        .home = "/home/Lucy" 
                      }; 

( 3)乱序(C++风格)
C++风格的乱序初始化方式跟C风格的一样,只是它更常用在C++代码里。
gcc不支持后缀名为cpp的文件使用这种方式!!!!(待确认)

struct User oneUser = { 
                       name:"Lucy",  
                       id:10, 
                       home:"/home/Lucy" 
                      }; 

拷贝

struct有两种拷贝方式,一是直接赋值(=),另一种是用memcpy等库函数实行内存拷贝。
eg:

        struct Temp a, b;
        //Set value to members of b
        a = b;
        memcpy(&a, &b, sizeof(a));

不管是哪种拷贝方式,都是将以&b开始的,大小为sizeof(struct Temp)的内存区域中的数据,简单地复制到以&a开始的,同样大小的内存区域。所以,这两种方式与按成员赋值是等价的:

        a.id = b.id;
        a.name = b.name;
        a.home = b.home;
        a.passwd = b.passwd;

由此,我们不难看出,上面两种拷贝方式都属于浅拷贝。

指针成员的两种使用技巧

(1) 为多个指针成员同时分配内存
如果一个struct中有多个指针类型的成员,我们通常需要为每个指针逐个成员分配内存空间,并在使用完时释放它们;这样频繁调用malloc/free,难免让人生厌。如果在分配内存之前,每个指针所指向内存区域的大小是确定的,那么,我们可以为所有指针一次性分配内存区域;并在使用完后,一次性释放。
eg:

  struct Inode{
          int id;
          char *file;
          int fie_len;
          char *path;
          int path_len;
          char *user;
          int user_len;
       };
struct Inode data = {
                     .file_len = X,
                     .path_len = Y,
                     .user_len = X
                     };

       //Allocate memory
       data.file = (char *)malloc(data.file_len + data.path_len + data.user_len);  // 一下子分配所有内存,只适用于知道内存大小
       data.path = data.file + data.file_len;
       data.user = data.path + data.path_len;
       //User
       ...
       //Free memory
       free(data.file);

2)变长数组的另类实现
将下面的定义

     struct File
       {
          TypeA dataA;
          ......
          char *data;
          TypeN dataN;         
       };
改成:
       struct File
       {
          TypeA dataA;
          ......         
          TypeN dataN;   
          char data[0];        // 定义大小为0的一维数组,且放在最后,实际上是利用数组越界访问!!!
       };

即将指针成员换成大小为0的一维数组, 作为struct的最后一个成员(数据结构的可变部分必须作为最后一个成员),(这个有点呵呵!!!!)有两个优点:
(1) 在紧邻struct处为data分配内存区域,这样在分配内存后无须为data赋值;
(2) 利用数组的特性,以指针的方式通过越界访问data数组外的内存区域。
eg:

       struct File *pVar = (struct File *)malloc(sizeof(struct File) + DATA_LEN);
       strncpy(pVar->data, "Source data", DATA_LEN);

C和C++中的区别

  • C++语言将struct当成类来处理的,所以C++的struct可以包含C++类的所有东西,例如构造函数,析构函数,友元等,C++的struct和C++类唯一不同就是struct成员默认的是public, C++默认private。而C语言struct不是类,不可以有函数,也不能使用类的特征例如public等关键字 ,也不可以有static关键字。C++ struct里面成员初始化的形式和类是相同的,不可以直接初始化,就是不可以定义成员的时候同时初始化。C语言 struct中间的某个类型(例如int)也不可以直接初始化。 就是说下面int a = 0;在C++和C语言里面都是不能通过的。
struct HE
{
      int a = 0;
}
//C++和C编译是不能通过的。
  • 初始化方式,C++ struct的初始化,C++不仅拥有C语言的初始化方式。如下:
struct HE{
     int a;
};
int main(){
    HE d={3};  
    // 因为 HE在C++是类名,可以省略struct。C语言里面要加上struct 才行。
    return 0;
}
  • 也可以使用类的初始化方式
struct HE{
     int a;

};
int main(){
    HE d; 
    d.a = 3;
    return 0;
}
  • 类型不同,下面代码:
struct HE{
     int a;      
};

在C里面实际上数据类型为 (struct HE),所以定义一个结构HE变量都要 带上struct.
struct HE a; //C语言 变量方式
而在C++里面实际上数据类型为HE(主要是因为结构体被当成类对待了),所以定义变量不需要 struct.
HE a; //C++语言 变量

  • typedef struct 在C++和C语言中都是一样的功能,定义别名。 但是要注意下面的代码的区别
#include <stdio.h>
#include <stdlib.h>
typedef struct HE    
{
     int a;

} *PHE,DHE,EHE; //这是定义了一个struct HE*类型别名和两个普通别名,main函数只考虑指针型别名。
int main(){
    PHE a = (PHE)malloc(sizeof(struct HE)); //这是C语言的写法
    //PHE a = new HE();   这是C++语言的写法
    return 0;
#include <stdio.h>
#include <stdlib.h>
struct HE    
{
     int a;

} *PHE,DHE,EHE; //这里定义了一个指针型变量和两个普通变量

上面两个代码省略 struct的名字 HE都是可以的。

总结:C++语言因为是和C语言兼容的,所以C语言的语法在C++编译器里不会出错,但是程序员最好知道什么是C语言,什么是C++语言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值