C 结构体小结
看了三天结构体,是时候总结一下了。
关于结构体的声明:

struct Student
{
char name[];
char sex;
int age;
char addr[];
};
/*然后定义一个Student 类型的 student变量*/
struct Student student;

也许是我受了Java影响,我一度写成这样:

struct man
{
int age = ;
int score = ;
}; int main()
{
man man1 = {,}; }

结果是铁定编译通过不了的。因为这是我自创的声明带默认值的结构体,编译器没见过。结构体成员变量在声明中是不能赋值的。
正确的写法是:

struct Man
{
int age; //这样就好了
int score;
}; int main()
{
struct Man man1 = {,};
}

定义结构体的时候每次都要写struct 显然是烦琐了,精炼的C语言用来typedef来方便定义使用:

typedef struct Man
{
int age;
int score;
}man; int main()
{
man man1 = {,};
man man2 = {,};
man man3 = {,};
printf("%d\n",man1.age);
printf("%d\n",man3.score);
}

这样一来大家想召唤多少个“男人”都没有问题。另外有一个极端一点的问题,声明结构体名和定义结构体变量名能不能一样?我们可以试试看:

typedef struct man
{
int age;
int score;
}man; //还叫man,有意见么? int main()
{
man man = {,};//还叫man,有问题么?
printf("%d\t%d\n",man.age,man.score);
}

编译运行都是没有问题的。不信自己去试试看。
然后我们来讨论重点吧:

struct Student
{
char name[];
char sex;
int age;
char addr[];
};
/*然后定义一个Student 类型的 student变量*/
struct Student student;

给定义的结构中name和age赋值, 可以用下面语句:
strcpy(student->name, "jack");
student->age=21;
student->name就是(*student).name的缩写形式。
需要指出的是结构指针是指向结构的一个指针, 是结构中第一个成员的首地址, 因此在使用之前应该对结构指针初始化, 即分配整个结构长度的字节空间, 这可用下面函数完成, 仍以上例来说明如下:
student=(struct string*)malloc(size of (struct string));
size of (struct string)自动求取string结构的字节长度, malloc() 函数定义了一个大小为结构长度的内存区域, 然后将其诈地址作为结构指针返回。
注意:
结构变量名不是指向该结构的地址, 这与数组名的含义不同, 因此若需要求结构中第一个成员的首地址应该是&[结构变量名]。
联合体
联合体的结构定义和结构体大体相似。
当一个联合被说明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度。
联合既可以出现在结构内, 它的成员也可以是结构。
例如:

struct{
int age;
char *addr;
union{
int i;
char *ch;
}x;
}y[];

若要访问结构变量y[1]中联合x的成员i, 可以写成:
y[1].x.i;
若要访问结构变量y[2]中联合x的字符串指针ch的第一个字符可写成:
*y[2].x.ch;
若写成"y[2].x.*ch;"是错误的。值得指出的是此时的*y[2].x.ch是一个没有分配内存地址的野指针,直接赋值给它在运行时会崩溃。
结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员, 而结构的所有成员都存在。
对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。
下面举一个例了来加对深联合的理解。

int main()
{
union{ /*定义一个联合*/
int i;
struct{ /*在联合中定义一个结构*/
char first;
char second;
}half;
}number;
number.i=0x4241; /*联合成员赋值*/
printf("%c%c\n", number.half.first, mumber.half.second);
number.half.first='a'; /*联合中结构成员赋值*/
number.half.second='b';
printf("%x\n", number.i);
}

输出结果为:
AB
6261
从上例结果可以看出: 当给i赋值后, 其低八位也就是first和second的值; 当给first和second赋字符后, 这两个字符的ASCII码也将作为i 的低八位。
用结构体写一个单链表的雏形

#include <stdio.h>
struct node { struct node *link;
int value; }; void main() {
struct node node1, node2, node3;
struct node *head; //定义链表头指针
node1.value = ; //定义各个节点的内部属性值
node2.value = ;
node3.value = ;
head = &node1; //头指针指向第一个节点的地址 node1.link = &node2;//第一个节点的指针指向第二个节点的地址
node2.link = &node3;//第二个节点的指针链接到第三个节点的地址
node3.link = NULL; //第三个节点的地址为空 /*打印输出*/ struct node *p;
p = head;
while(p != NULL)
{
printf("%d\n", p->value);
p = p->link;//移动指针到下一个节点 }
}

之所以说它是一个单链表的雏形,因为他是在是太不完整了,但是至少他已经有单链表的影子了。我将慢慢完善改进它。
总结给自己看的,所以整理了我认为重要的部分。
C 结构体小结的更多相关文章
- 零基础逆向工程11_C语言05_结构体
结构体小结 结构体是按照分配的大小,局部变量会自动数据对齐 1字节对齐,省空间,但cpu查找效率低 4字节对齐,不省空间,但cpu查找效率高 VC6默认的结构对齐大小 项目右键-> settin ...
- 结构体定义 typedef struct 用法详解和用法小结
typedef是类型定义的意思.typedef struct 是为了使用这个结构体方便.具体区别在于:若struct node {}这样来定义结构体的话.在申请node 的变量时,需要这样写,stru ...
- TCP/IP协议头部结构体(网摘小结)(转)
源:TCP/IP协议头部结构体(网摘小结) TCP/IP协议头部结构体(转) 网络协议结构体定义 // i386 is little_endian. #ifndef LITTLE_ENDIAN #de ...
- C#类与结构体的小结
1.定义不同 类使用class关键字来定义: 结构体用struct: 2.使用时的注意事项 ->结构体是值类型,类是引用类型 ->结构体中声明的变量不能做赋值操作,但是类可以. -> ...
- C结构体struct用法小结
结构体和int,float等类型一样是一种常用的类型,它是由各种基本数据类型构成,通常包含有struct关键字,结构体名,结构体成员,结构体变量. 一.结构体定义 通常有3种定义方式,以例子方式表示: ...
- C++结构体中使用函数与类中使用函数小结
#include <iostream>#include <string.h>using namespace std;struct stud//学生信息结构体{ char ...
- p/invoke碎片,对结构体的处理
结构体的一些相关知识 可直接转换类类型,比如int类型,在托管代码和非托管代码中占据内存大小 和意义都是一个样的. 结构体封送的关键是:在托管代码和非托管代码中定义的一致性.什么是定义的一致性?包括结 ...
- c语言结构体1之定义
这是在复习阶段随便小结的一些东西 别喷哦 结构体定义的三种方式 注意事项: 1结构体括号后面有分号 2#define得放在程序上面 3成员名可以和结构体名相同 4结构体类型不能直接访问成员,也不能赋值 ...
- c语言博客作业--结构体&文件
1.本章学习总结 1.1思维导图 1.2.本章学习体会 本章学到了结构体如何构建,用typedef进行重定义结构体,结构指针,访问结构体的方式等. 文件:文件的读取,文件读写的几个函数,基本了解了文本 ...
随机推荐
- solr导入mysql数据库
感谢ITeye的博主viskyzz分享的经验,笔者基本参考ta的方法.然而,解决中间出现的问题时也融入了自己的经验. 查看ta的原文请戳: http://tbwuming.iteye.com/blog ...
- echo 和 cat 的 区别
tt="1 10 17 10-134-9-154.xml" echo $tt 只是单纯地打印出tt保存的这些变量 cat $tt 则会对tt 中保存的变量文件挨个打印出来
- 【蒟蒻の进阶PLAN】 置顶+持续连载
看到周围神犇们纷纷列计划,本蒟蒻也决定跟随他们的步伐,计划大约是周计划吧,具体怎么安排我也不确定.. 2015.12.30 刚刚学习完最基础的网络流,需要进行这方面的练习,从简到难,有空余的话尝试学习 ...
- 洛谷P2731骑马修栅栏
题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个 ...
- appium-向右滑动定位
上面5幅欢迎图,要向右滑动4次再点击[立即体验]才可以到首屏 #首页欢迎图滑动4次 for i in range(4): driver.swipe(1200, 200, 10, 200, 1500) ...
- POJ3259Wormholes(判断是否存在负回路)
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 38300 Accepted: 14095 Descr ...
- python + selenium + PhantomJS 获取腾讯应用宝APP评论
PhantomJS PhantomJS 是一个基于WebKit的服务器端JavaScript API,它无需浏览器的支持即可实现对Web的支持,且原生支持各种Web标准,如DOM 处理.JavaScr ...
- Java Observer 观察者
http://www.cnblogs.com/jaward/p/3277619.html 1.API 被观察者 java.util.Observable; public class Observabl ...
- SQL2005删除复制数据库的发布与订阅的方法(转载)
SQL2005删除复制数据库的发布与订阅的方法 --在测试环境中恢复从正式数据库服务器 上备份下来的bak文件后,正式环境里数据库复制的发布.订阅也被带进来了,结果恢复的数据库无法更改表结构,直接删除 ...
- 高性能的分布式内存对象缓存系统Memcached
Memcached概述 什么是Memcached? 先看看下面几个概念: Memory:内存存储,不言而喻,速度快,对于内存的要求高,不指出的话所缓存的内容非持久化.对于CPU要求很低,所以常常采 ...