全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

C语言结构体(struct)常见使用方法(细节问题)

基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合)的变量封装在内部,通过一定方法访问修改内部变量。

结构体定义:

第一种:只有结构体定义

struct stuff{ 
    char job[20]; 
    int age; 
    float height; 
}; 

第二种:附加该结构体类型的“结构体变量”的初始化的结构体定义

//直接带变量名Huqinwei 
struct stuff{ 
    char job[20]; 
    int age; 
    float height; 
}Huqinwei; 

也许初期看不习惯容易困惑,其实这就相当于:

struct stuff{ 
    char job[20]; 
    int age; 
    float height; 
}; 
struct stuff Huqinwei; 

第三种:如果该结构体你只用一个变量Huqinwei,而不再需要用

struct stuff yourname; 

去定义第二个变量。

那么,附加变量初始化的结构体定义还可进一步简化出第三种:

struct{ 
    char job[20]; 
    int age; 
    float height; 
}Huqinwei; 

把结构体名称去掉,这样更简洁,不过也不能定义其他同结构体变量了——至少我现在没掌握这种方法。

结构体变量及其内部成员变量的定义及访问:

绕口吧?要分清结构体变量和结构体内部成员变量的概念。

就像刚才的第二种提到的,结构体变量的声明可以用:

struct stuff yourname; 

其成员变量的定义可以随声明进行:

struct stuff Huqinwei = {"manager",30,185}; 
也可以考虑结构体之间的赋值:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
    struct stuff faker = Huqinwei; 
//或  struct stuff faker2; 
//   faker2 = faker; 

打印,可见结构体的每一个成员变量一模一样 

如果不使用上边两种方法,那么成员数组的操作会稍微麻烦(用for循环可能好点)

Huqinwei.job[0] = 'M'; 
Huqinwei.job[1] = 'a'; 
Huqinwei.age = 27; 
nbsp;Huqinwei.height = 185; 

结构体成员变量的访问除了可以借助符号".",还可以用"->"访问(下边会提)。

引用(C++)、指针和数组:

首先是引用和指针:

int main() 
{ 
    struct stuff Huqinwei; 
    struct stuff &ref = Huqinwei; 
    ref.age = 100; 
    printf("Huqinwei.age is %d\n",Huqinwei.age); 
    printf("ref.age is %d\n",ref.age); 
    struct stuff *ptr = &Huqinwei; 
    ptr->age = 200; 
    printf("Huqinwei.age is %d\n",Huqinwei.age); 
    printf("ptr->age is %d\n",Huqinwei.age); 
//既然都写了,把指针引用也加上吧 
    struct stuff *&refToPtr = ptr; 
    refToPtr->age = 300; 
    printf("Huqinwei.age is %d\n",Huqinwei.age); 
    printf("refToPtr->age is %d\n",refToPtr->age); 
}

更正:之前给引用的初始化语句写错了,而且没注明引用是纯C中没有的东西(在这么个以C为幌子的博客中)。

引用是C++特有的一个机制,必须靠编译器支撑,至于引用转换到C中本质是什么,我有个帖子写过

结构体也不能免俗,必须有数组:

struct test{ 
    int a[3]; 
    int b; 
}; 
//对于数组和变量同时存在的情况,有如下定义方法: 
    struct test student[3] =   {{{66,77,55},0}, 
                    {{44,65,33},0}, 
                    {{46,99,77},0}}; 
//特别的,可以简化成: 
    struct test student[3] =    {{66,77,55,0}, 
                    {44,65,33,0}, 
                    {46,99,77,0}}; 

变长结构体

可以变长的数组

#include <stdio.h> 
#include <malloc.h> 
#include <string.h> 
typedef struct changeable{ 
    int iCnt; 
    char pc[0]; 
}schangeable; 
main(){ 
    printf("size of struct changeable : %d\n",sizeof(schangeable)); 
    schangeable *pchangeable = (schangeable *)malloc(sizeof(schangeable) + 10*sizeof(char)); 
    printf("size of pchangeable : %d\n",sizeof(pchangeable)); 
    schangeable *pchangeable2 = (schangeable *)malloc(sizeof(schangeable) + 20*sizeof(char)); 
    pchangeable2->iCnt = 20; 
    printf("pchangeable2->iCnt : %d\n",pchangeable2->iCnt); 
    strncpy(pchangeable2->pc,"hello world",11); 
    printf("%s\n",pchangeable2->pc); 
    printf("size of pchangeable2 : %d\n",sizeof(pchangeable2)); 
} 

运行结果

size of struct changeable : 4 
size of pchangeable : 4 
pchangeable2->iCnt : 20 
hello world 
size of pchangeable2 : 4 

结构体本身长度就是一个int长度(这个int值通常只为了表示后边的数组长度),后边的数组长度不计算在内,但是该数组可以直接使用。

(说后边是个指针吧?指针也占长度!这个是不占的!原理很简单,这个东西完全是数组后边的尾巴,malloc开辟的是一片连续空间。其实这不应该算一个机制,感觉应该更像一个技巧吧)

20160405补充:

非弹性数组不能用"char a[]"这种形式定义弹性(flexible)变量,必须明确大小。

弹性数组在结构体中,下面的形式是唯一允许的:

struct s 
{ 
    int a; 
    char b[] ; 
}; 

顺序颠倒会让b和a数据重合,会在编译时不通过。

char b[] = "hell";也不行(C和C++都不行)

少了整型变量a又会让整个结构体长度为0,compiler不允许编译通过!不同的是,其实C++形式上是允许空结构体的,本质上是通过机制避免了纯空结构体和类对象,自动给空结构体对象分配一个字节(sizeof()返回1)方便区分对象,避免地址重合!所以呢,C如果有空结构体,定义两个(或一打,或干脆一个数组)该结构体的变量(对象),地址是完全一样的!·!!!!!!!!调试看程序运行,这些语句其实都被当屁放了,根本没有运行,没有实际意义,C压根不支持空结构体这种东西(或者说我也没想好什么场合有用)

struct s2 
{ 
//   char a[] = "hasd" ; 
//   int c; 
}; 
int main() 
{ 
    struct s2 s22; 
    struct s2 s23; 
    struct s2 s24; 
    struct s2 s25; 
} 

例外的是,C++唯独不给带弹性数组的结构体分配空间(可能怕和变长结构体机制产生某种冲突,比如大小怎么算):

struct s 
{ 
    char b[] ; 
}; 
struct s 
{ 
//    char b[] ; 
}; 

C++中两者是不一样的,空的结构体反而“大”(sizeof()返回1)

20160321补充:

这个机制利用了一个非常重要的特性——数组和指针的区别!数组和指针在很多操作上是一样的,但是本质不一样。最直观的,指针可以改指向,数组不可以,因为数组占用的每一个内存地址都用来保存变量或者对象,而指针占用的内存地址保存的是一个地址,数组没有单独的保存指向地址的这样一个结构。数组的位置是固定的,正如指针变量自身的位置也是固定的,改的是指针的值,是指向的目标地址,而因为数组不存储目标地址,所以改不了指向。企图把地址强制赋值给数组的话,也只是说把指针赋值给数组,类型不兼容。

结构体嵌套:

结构体嵌套其实没有太意外的东西,只要遵循一定规律即可:

//对于“一锤子买卖”,只对最终的结构体变量感兴趣,其中A、B也可删,不过最好带着 
struct A{  
    struct B{ 
       int c; 
    } 
    b; 
} 
a; 
//使用如下方式访问: 
a.b.c = 10;  

特别的,可以一边定义结构体B,一边就使用上:

struct A{ 
    struct B{ 
        int c; 
    }b; 
    struct B sb; 
}a; 

使用方法与测试:

    a.b.c = 11; 
    printf("%d\n",a.b.c); 
    a.sb.c = 22; 
    printf("%d\n",a.sb.c); 

结果无误。  

但是如果嵌套的结构体B是在A内部才声明的,并且没定义一个对应的对象实体b,这个结构体B的大小还是不算进结构体A中。

结构体与函数:

关于传参,首先:

void func(int); 
func(a.b.c); 

把结构体中的int成员变量当做和普通int变量一样的东西来使用,是不用脑子就想到的一种方法。

另外两种就是传递副本和指针了 :

//struct A定义同上 
//设立了两个函数,分别传递struct A结构体和其指针。 
void func1(struct A a){ 
    printf("%d\n",a.b.c); 
} 
void func2(struct A* a){ 
    printf("%d\n",a->b.c); 
} 
main(){ 
    a.b.c = 112; 
    struct A * pa; 
    pa = &a; 
    func1(a); 
    func2(&a); 
    func2(pa); 
} 

占用内存空间:

struct结构体,在结构体定义的时候不能申请内存空间,不过如果是结构体变量,声明的时候就可以分配——两者关系就像C++的类与对象,对象才分配内存(不过严格讲,作为代码段,结构体定义部分“.text”真的就不占空间了么?当然,这是另外一个范畴的话题)。

结构体的大小通常(只是通常)是结构体所含变量大小的总和,下面打印输出上述结构体的size:

 printf("size of struct man:%d\n",sizeof(struct man)); 
    printf("size:%d\n",sizeof(Huqinwei)); 

结果毫无悬念,都是28:分别是char数组20,int变量4,浮点变量4.  

下边说说不通常:

对于结构体中比较小的成员,可能会被强行对齐,造成空间的空置,这和读取内存的机制有关,为了效率。通常32位机按4字节对齐,小于的都当4字节,有连续小于4字节的,可以不着急对齐,等到凑够了整,加上下一个元素超出一个对齐位置,才开始调整,比如3+2或者1+4,后者都需要另起(下边的结构体大小是8bytes),相关例子就多了,不赘述。

struct s 
{ 
char a; 
short b; 
int c; 
} 

相应的,64位机按8字节对齐。不过对齐不是绝对的,用#pragma pack()可以修改对齐,如果改成1,结构体大小就是实实在在的成员变量大小的总和了。

和C++的类不一样,结构体不可以给结构体内部变量初始化,。

如下,为错误示范:

#include<stdio.h> 
//直接带变量名Huqinwei 
struct stuff{ 
//   char job[20] = "Programmer"; 
//   char job[]; 
//   int age = 27; 
//   float height = 185; 
}Huqinwei; 

PS:结构体的声明也要注意位置的,作用域不一样。

C++的结构体变量的声明定义和C有略微不同,说白了就是更“面向对象”风格化,要求更低。

那么熟悉了常用方法,都要注意哪些常犯错误呢,见C语言结构体常见错误。

以上所述是小编给大家介绍的C语言结构体(struct)常见使用方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# c语言结构体struct  # struct结构体  # C语言struct结构体介绍  # 详解C语言中结构体(struct)的用法  # C语言 struct结构体超详细讲解  # C语言结构体(struct)的详细讲解  # C语言中结构体(struct)的几种初始化方法  # C语言 结构体(Struct)详解及示例代码  # C语言结构体struct详解  # 的是  # 就像  # 两种  # 可以用  # 不可以  # 变长  # 第二种  # 小编  # 第三种  # 不占  # 体内  # 都是  # 这是  # 变量名  # 是个  # 是在  # 带着  # 都要  # 浮点  # 在此 


相关文章: 小型网站制作HTML,*游戏网站怎么搭建?  西安专业网站制作公司有哪些,陕西省建行官方网站?  制作销售网站教学视频,销售网站有哪些?  网站制作企业,网站的banner和导航栏是指什么?  如何在腾讯云免费申请建站?  威客平台建站流程解析:高效搭建教程与设计优化方案  如何在景安云服务器上绑定域名并配置虚拟主机?  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  临沂网站制作企业,临沂第三中学官方网站?  在线制作视频的网站有哪些,电脑如何制作视频短片?  已有域名和空间,如何快速搭建网站?  怀化网站制作公司,怀化新生儿上户网上办理流程?  免费ppt制作网站,有没有值得推荐的免费PPT网站?  如何在阿里云高效完成企业建站全流程?  网站设计制作企业有哪些,抖音官网主页怎么设置?  开心动漫网站制作软件下载,十分开心动画为何停播?  建站之星如何配置系统实现高效建站?  如何快速打造个性化非模板自助建站?  PHP 500报错的快速解决方法  武汉网站制作费用多少,在武汉武昌,建面100平方左右的房子,想装暖气片,费用大概是多少啊?  ppt制作免费网站有哪些,ppt模板免费下载网站?  如何选择高性价比服务器搭建个人网站?  高性价比服务器租赁——企业级配置与24小时运维服务  建站之星各版本价格是多少?  Android自定义控件实现温度旋转按钮效果  开封网站制作公司,网络用语开封是什么意思?  建站主机如何选?高性价比方案全解析  网站制作难吗安全吗,做一个网站需要多久时间?  广州美橙建站如何快速搭建多端合一网站?  ui设计制作网站有哪些,手机UI设计网址吗?  深圳网站制作案例,网页的相关名词有哪些?  沈阳制作网站公司排名,沈阳装饰协会官方网站?  早安海报制作网站推荐大全,企业早安海报怎么每天更换?  如何快速搭建安全的FTP站点?  油猴 教程,油猴搜脚本为什么会网页无法显示?  建站VPS配置与SEO优化指南:关键词排名提升策略  网站代码制作软件有哪些,如何生成自己网站的代码?  c# 在高并发下使用反射发射(Reflection.Emit)的性能  如何制作网站标识牌,动态网站如何制作(教程)?  ,制作一个手机app网站要多少钱?  长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?  建站之星如何实现五合一智能建站与营销推广?  手机网站制作与建设方案,手机网站如何建设?  专业网站设计制作公司,如何制作一个企业网站,建设网站的基本步骤有哪些?  建站之星如何快速生成多端适配网站?  宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?  湖州网站制作公司有哪些,浙江中蓝新能源公司官网?  网站制作话术技巧,网站推广做的好怎么话术?  建站主机选购指南:核心配置与性价比推荐解析  建站之星安装提示数据库无法连接如何解决? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。