C语言-结构体的3种用途

C语言-结构体的3种用途

返回脚本百事通
1.通过结构体, 从函数中返回多个数据元素
例1:
/* 函数同时返回包含秒和微秒的时间差 */
typedef struct {
int tv_sec;
int tv_usec;
} timeval;

static timeval difftv(timeval a, timeval b)
{
static timeval diff;

diff.tv_sec = b.tv_sec - a.tv_sec;
if ((diff.tv_usec = b.tv_usec - a.tv_usec) < 0) {
diff.tv_sec--;
diff.tv_usec += 1000000;
}
return diff;
}



2.结构体可以映射数据的组织方式
例1.
/*fxp_cb_nop表示了Intel EtherExpress网卡的一个控制块*/
struct fxp_cb_nop {
	void *fill[2];
	volatile u_int16_t cb_status;
	volatile u_int16_t cb_command;
	volatile u_int32_t link_addr;
};
volatile 修饰符用来表明底层的内存字段将被程序之外的实体(上例为网卡)使用, 从而禁止编译器对其进行移除冗余引用之类的优化.

例2.结构体中使用bit-field语法定义只占几个bit的成员:

/* 使用位域(bit-field)来划分出精确的bit区域, 以保存指定设备上的特定数据 */
typedef struct {
unsigned int one:1;
unsigned int two:3;
unsigned int three:10;
unsigned int four:5;
unsigned int :2;
unsigned int five:8;
unsigned int six:8;
} demo_type;

int main(void)
{
demo_type s = { 1, 5, 513, 17, 129, 0x81 };
printf("sizeof demo_type = %u\n", sizeof(demo_type));
printf("values: s=%u,%u,%u,%u,%u,%u\n",
s.one, s.two, s.three, s.four, s.five, s.six);

return 0;
}


例3.
struct fxp_cb_config {
[...]
volatile u_int8_t byte_count:6,
:2;
volatile u_int8_t rx_fifo_limit:4,
tx_fifo_limit:3,
:1;
};
用来传递数据的byte_count占据了6bit的空间, 而数据的接收者和传送者的FIFO队列限制在硬件设备上分别占据了4bit和3bit的空间. 那个':2'和':1'是未命名的bit-field, 即使不写未命名的bit-field, 编译器也可能在两个成员之间插入填充位. 这样使访问效率提高.

例4:
/* TCP报文的经典定义 */
struct tcphdr {
u_int16_t th_sport; /* source port */
u_int16_t th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
[...]
};



3.以面向对象的方式编程
通过结构体将相关数据和函数指针封装在一起, 来模拟类的字段和方法, 从而创建类似对象的实体.
例1:
/* 结构体domain用来表示网络协议(Internet, SNA, IPX)中的不同的域
* 它封装了与特定域相关的数据(比如域所属的家族dom_family)和
* 操作这些数据的方法(比如路由表的初始化方法) */
struct domain {
int dom_family; /* AF_xxx */
char *dom_name;
void (*dom_init)(void); /* initialize domain data structures */
[...]
int (*dom_rtattach)(void **, int);
/* initialize routing table */
int dom_rtoffset; /* an arg to rtattach, in bits */
int dom_maxrtkey; /* for routing layer */
};
该结构体类型的变量或指针(更常见)在完成初始化以后, 就可以像C++或Java对象那样
使用了.
for (dom = domains; dom; dom = dom->dom_next)
if (dom->dom_family == i && dom->dom_rtattach) {
dom->dom_rtattach((void **)&nep->ne_rtable[i],
dom->dom_rtoffset);
break;
[...]
}



例2:
/* 因为同一类型的对象共享了相同的方法(函数指向了相同的函数地址)
* 所以, "对象"通常只存储一个指向另一结构体的指针,
* 由这个结构体负责存储指向实际方法的指针,
* 从而达到在不同对象之间共享方法指针的目的 */
struct file {
[...]
short f_type; /* descriptor type */
short f_count; /* reference count */
short f_msgcount; /* reference from message quene */
struct ucred *f_cred; /* credentials associated with descriptor */
struct fileops {
int (*fo_read)(struct file *fp, struct uio *uio,
struct ucred *cred);
int (*fo_write)(struct file *fp, struct uio *uio,
struct ucred *cred);
int (*fo_ioctl)(struct file *fp, u_long com,
caddr_t data, struct proc *p);
int (*fo_poll)(struct file *fp, int events,
struct proc *p);
int (*fo_close)(struct file *fp, struct proc *p);
} *f_ops;
off_t f_offset;
caddr_t f_data; /* vnode or socket */
}


作者:byguess 发表于2013-4-22 12:12:17  原文链接
<think>首先,用户要求使用中文回答问题。所以,我的整个响应必须是中文的。 用户的问题是:"c语言结构体说明一下",意思是"解释一下C语言结构体"。 我需要提供一个关于C语言结构体的解释。结构体是C语言中一种复合数据类型,允许用户组合不同类型的数据项。 关键点包括: - 结构体使用`struct`关键字定义。 - 它可以包含多个成员,每个成员可以是不同的数据类型。 - 结构体用于创建自定义数据类型。 - 示例:定义一个学生结构体,包含姓名、年龄等。 我应该给出一个简单的代码示例来展示结构体的定义和使用。 在回答完问题后,我必须根据用户的问题和我的回答提出3-5个相关问题。这些相关问题必须以"§§相关问题§§"开头,并且不能换行分散;它必须是一行完整的输出。 从示例格式中: - 回答部分包括解释和代码块。 - 然后,直接输出"§§相关问题§§",后跟1. 2. 3. 等编号的问题。 相关问题必须基于用户的问题和我的回答。所以,既然问题是关于C语言结构体的,问题应该涉及结构体的相关方面,比如初始化、访问成员、指针等。 列出可能的3-5个相关问题: 1. 如何初始化一个结构体变量? 2. 结构体和数组有什么区别? 3. 如何在函数中使用结构体指针? 4. 结构体可以包含其他结构体吗? 5. 如何访问结构体的成员? 确保问题数量在3到5个之间。 现在,构建我的响应: 1. 先用中文解释结构体。 2. 提供一个简单的代码示例。 3. 然后,输出"§§相关问题§§",后跟编号的问题列表。 代码示例应该用Markdown代码块表示,如示例中所示。 完整响应结构: - 解释部分。 - 代码示例。 - "§§相关问题§§" - 相关问题列表。 写响应: 解释:C语言结构体是一种用户自定义的数据类型,它允许你将不同类型的数据组合成一个单一的实体。结构体使用`struct`关键字定义,可以包含多个成员变量。 代码示例:定义一个学生结构体,并创建一个实例。 ```c #include <stdio.h> // 定义结构体 struct Student { char name[50]; int age; float score; }; int main() { // 创建结构体变量 struct Student student1; // 初始化结构体成员 strcpy(student1.name, "张三"); student1.age = 20; student1.score = 85.5; // 访问并打印结构体成员 printf("姓名: %s\n", student1.name); printf("年龄: %d\n", student1.age); printf("分数: %.1f\n", student1.score); return 0; } ``` 然后,相关问题: §§相关问题§§ 1. 如何动态分配结构体内存? 2. 结构体数组如何定义和使用? 3. 结构体与联合体有什么区别? 4. 如何在函数中传递结构体参数? 确保相关问题合理相关。</think>C语言结构体(struct)是一种用户自定义的复合数据类型,允许你将多个不同类型的数据项组合成一个单一的实体。结构体使用 `struct` 关键字定义,每个数据项称为成员(member)。其主要用途是创建复杂的数据结构,例如表示学生、员工或坐标点等实体。 ### 关键特点: 1. **定义语法**:使用 `struct` 声明,后跟结构体名和成员列表。 2. **成员类型**:成员可以是基本类型(如 int、char、float)或其他结构体3. **访问成员**:通过点运算符 `.` 访问成员变量。 4. **内存对齐**:结构体的大小由成员大小和对齐规则决定(可通过 `sizeof` 获取)。 5. **灵活性**:支持结构体数组、指针和嵌套结构体。 ### 示例代码: 以下是一个简单的结构体定义和使用示例: ```c #include <stdio.h> // 定义结构体 struct Person { char name[50]; int age; float height; }; int main() { // 创建结构体变量 struct Person person1; // 初始化成员 strcpy(person1.name, "李四"); // 字符串赋值 person1.age = 25; person1.height = 175.5; // 访问并打印成员 printf("姓名: %s\n", person1.name); printf("年龄: %d\n", person1.age); printf("身高: %.1f cm\n", person1.height); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值