C语言结构体小结

在学习C语言的过程中,很多新手会觉得结构体并没有什么卵用,C语言内置的数据类型int呀,double呀已经可以解决我们所碰到的大部分编程问题,然而生活不是编程题,它会给你各种各样用内置数据类型解决不了的难题,这时候就用到了结构体这个神奇的玩意


结构体的定义和初始化

struct stu{

int xuehao;//学号

int score;//分数

char name[10];//名字

}xiaohong = {141089,60,"xiaohong"};//结构体写完需要加分号,因为它虽然有大括号,但它不是一个函数,而是一个数据定义和初始化的过程,像 int x;


上面是一种初始化的方法,还可以这样写

struct stu xiaoming = {414090,100,"xiaoming"};


说到结构体就不得不说typedef

typedef 你可以把它看成是一个命名规则,比如:

typedef struct stu{

int xuehao;

int score;

char name[10];

}STU;


这个时候你初始化或者定义结构体变量就可以这么写:

STU xiaohu = {414091,59,"xiaohu"};


结构体的初始化有一个最大的深坑,几乎每个程序猴都得跳进去一次,这里就来讲一讲这个坑

STU xiaojian ;

xiaojian = {414096,88,"xiaojian"};

相信有很多人会这么写,因为我们见了很多下面的写法

int i;

i = 10;

但是,人家规定结构体跟数组只有定义和初始化在一起的时候才能这么写,否则不行!说到这里聪明的你可能想到了,虽然结构体定义后不能用大括号直接初始化,但是可以像操作数组元素那样进行初始化呀,是的,这就是定义后初始化结构体的唯一方法。在后面会讲结构体成员的引用中会介绍这种方法


这时候有人就要问了,typedef这玩意设计出来难道就是为了偷个懒?其实偷个懒是其次的,主要功能是用于某一个结构体有多种用途,用typedef可以给结构体起多个名字,比如在一个链表中可以这么写


typedef struct stu{

int xuehao,fenshu;

struct stu *p;

}STU,pSTU;

int main(){

pSTU *point;

STU xiaolong = {414095,89,point};

}


这里的STU和pSTU是一样的,都等于struct stu ,但是为什么要起两个名呢,是因为用处不同,STU所指的是一个链表的节点,而pSTU指的是这个节点的指针域里面存放的一个struct stu 类型的指针,这两个虽然都是struct stu,但是代表的意思是不一样的,就好像你在家里叫狗剩,到了正式场合就不能叫狗剩了,就应该叫杨爱国,赵爱军,宋爱党之类的了


说到这里又涉及到一个指针的问题,C语言中指针是必须指定一个数据类型的,为什么呢,指针就指针类型嘛,还指定什么类型。大错特错,其实在理解上我们不能把指针作为一种数据类型来看。因为我们的电脑系统不是抽象的,它是具体的,它要为每一个变量分配地址,一个指针在我看来有两种属性,第一是它自身的大小,32位系统下一个指针占四个字节,一般等同于一个int变量,第二是它指向的对象的类型(这里用了对象这个词,其实是因为在C++中认为对象是广义的,不光包括java中那种类的实例化,而且包括结构体和基本数据类型),比如:

int *p1;

p1++;

STU *p2;

p2++;

这时候p1与p2在内存上后移的位数就不一样,p1移动4个字节,而p2移动4+4+4=12个字节

正因为他们所指向的对象类型不同,所以指针位移的幅度也不同


好吧,说到这里又涉及到了一个结构体占内存的计算方法.......

简单来说就是结构体占内存不仅仅是按顺序排的,它有一个单位长度的概念,这个单位长度取决于结构体内最大的内置类型,比如上面的结构体,它们的三个成员类型都是4字节,所以占12字节,如果是:

struct str1{

int a;

char b;

int c;

};

这个也是占12字节,虽然char类型只占1字节,但它后面有3个空白位

但如果是:

struct str2{

int a;

char b;

short c;

};

这个结构体,只占8个字节,因为虽然char占1个字节,short占2个字节,但他们加起来没超过4个字节,所以把是short保存在char后面的空白字节中了


讲到这里我们普及一下基本数据类型的占内存空间,C语言只规定了最小的占内存空间,其它的组织或机构可以比这个大,但绝不能比标准的还小。而一般来说各个编译器或者操作系统中,char占1字节,short占2字节,int是4字节(最小2字节),long4字节(最小4字节)。

好了,我们回归正题


结构体的引用

结构体值引用有两种

  1. 用“.”来表示引用

    int main(){

    STU xiaopeng = {414092,61,"xiaopeng"};

    printf("%d\n",xiaopeng.xuehao);

    }

  2. 用指针来引用: (*p).xuehao 或 p->xuehao

    int main(){

    STU *p;

    STU xiaoyu = {414093,90,"xiaoyu"};

    printf("%d\n%d\n",(*p).xuhao,p->score);

    }

这时候就可以解决上面那个结构体定义后初始化的问题了,

xiappeng.xuehao = 141092;

(*p).xuehao = 141093;

p->score = 90;

这些都是合法的初始化和赋值方法,但是不要误会,初始化不是赋值,初始化不是赋值,初始化不是赋值,重要的事情要说三遍。


相信讲到这里即使聪明如你也已经懵逼了,因为我组织水平确实不高,不过耐心再看一遍,相信你会有所收获,毕竟这都是精华

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值