环境:redhat5.0
编译器:GCC
学习Linux得有良好的C语言基础,而C语言除了看书之外最重要的是通过项目或小例子来实践,这样有可能更深刻的理解书本上的内容。单看书不实践是没用的。
通过下面的小例子回顾一下结构体的几点内容:
1.结构体成员的定义
2.结构体成员的访问
3.结构体指针的使用
4.结构体的嵌套定义
5.typedef的使用
6.循环链表的了解
7.内存对齐
先看代码:
-
#include <stdio.h>
-
#include <string.h>
-
#include <semaphore.h>
-
-
#define MAX_EVENT 3
-
-
typedef struct EVENT_T{
-
int event[3];
-
struct EVENT_T *next;
-
}EVENT_T;
-
-
typedef struct INPUT_EVENT{
-
EVENT_T event[MAX_EVENT];
-
EVENT_T *read;
-
EVENT_T *write;
-
unsigned int cnt;
-
sem_t e_lock;
-
}INPUT_EVENT;
-
-
-
static INPUT_EVENT porting_event;
-
-
int Event_Struct_Init(void)
-
{
-
unsigned char i;
-
memset(&porting_event,0,sizeof(porting_event));
-
for(i = 0; i < MAX_EVENT - 1; i++)
-
{
-
porting_event.event[i].next = &porting_event.event[i + 1];
-
}
-
porting_event.event[MAX_EVENT-1].next = &porting_event.event[0];
-
porting_event.read = &porting_event.event[0];
-
porting_event.write = &porting_event.event[0];
-
porting_event.cnt = 0;
-
-
return 0;
-
}
-
-
void EVENTLink_Print(INPUT_EVENT *Link)
-
{
-
unsigned char i;
-
for(i = 0; ((Link->event[i].next) != NULL) && (i < (MAX_EVENT)); i++)
-
{
-
//Link->event[i].next is a pointer ,next line print zhe date in pointer's memory
-
printf("The Data of Link->event[%d].next is = 0x%p\n",i,Link->event[i].next);
-
//Link->event[i].next is a pointer ,next line print zhe address of pointer's
-
printf("The Address of Link->event[%d].next is = 0x%x\n",i,&(Link->event[i].next));
-
}
-
printf("Print sucessful\n");
-
}
-
-
int main(int argc , char *argv[])
-
{
-
int ret;
-
ret = Event_Struct_Init();
-
printf("---sizeof(porting_event) = %d---\n",sizeof(porting_event));
-
printf("---porting_event address is:0x%x---\n",&porting_event);
-
EVENTLink_Print(&porting_event);
-
return 0;
-
}
-
[root@localhost C_Func]# gcc struct_define.c -o struct_define
-
[root@localhost C_Func]# ./struct_define
-
---sizeof(porting_event) = 76---
-
---porting_event address is:0x8049800---
-
The Data of Link->event[0].next is = 0x0x8049810
-
The Address of Link->event[0].next is = 0x804980c
-
The Data of Link->event[1].next is = 0x0x8049820
-
The Address of Link->event[1].next is = 0x804981c
-
The Data of Link->event[2].next is = 0x0x8049800
-
The Address of Link->event[2].next is = 0x804982c
-
Print sucessful
根据开头提出的几点逐一说明:
1.结构体成员的定义:
结构体成员的定义C语言书上讲的很详细,可以参考。这里主要讲的是定义成员时,成员的类型是结构体本身的情况。又分为下面A、B两种。
A:成员类型是结构体本身。
B: 成员类型是结构体指针。
结构体的大小是在编译时决定的(实际内存分配是在定义结构体实际变量时)。
-
typedef struct EVENT_T{
-
int event[3];
-
struct EVENT_T *next;
-
}EVENT_T
A类情况,成员next是 struct EVENT_T类型变量,大小事sizeof(struct EVENT_T)。但sizeof(struct EVENT_T)到底是多大?跟进结构看看int event[3] = 4*3 =12byte,但next是多少呢?陷入无限循环中了。。。。
B类情况,next是个指针,所以其占用的内存大小是固定的4byte(在32位系统中指针本身占的内存是固定的,至于以后他指向其他内存有多大,那是后话),所以B类情况可以很明确的知道,sizeof(struct EVENT_T) = 12 + 4 = 16Byte。
2.结构体成员的访问
-
//Link->event[i].next is a pointer ,next line print zhe date in pointer's memory
-
printf("The Data of Link->event[%d].next is = 0x%p\n",i,Link->event[i].next); //输出next指针中的内容
-
//Link->event[i].next is a pointer ,next line print zhe address of pointer's
-
printf("The Address of Link->event[%d].next is = 0x%x\n",i,&(Link->event[i].next));//输出next指针本身的4字节地址//考虑 *(Link->event[i].next)的结果?
3.结构体指针的使用
-
void EVENTLink_Print(INPUT_EVENT *Link) //形参-指针
-
-
int main(int argc,char *argv[])
-
{
-
...
-
EVENTLink_Print(&porting_event); //实参-地址
-
...
-
}
4.结构体的嵌套定义
-
typedef struct EVENT_T{
-
int event[3];
-
struct EVENT_T *next;
-
}EVENT_T;
-
-
typedef struct INPUT_EVENT{
-
EVENT_T event[MAX_EVENT];
-
EVENT_T *read;
-
EVENT_T *write;
-
unsigned int cnt;
-
sem_t e_lock;
-
}INPUT_EVENT;
在struct INPUT_EVENT{}中插入结构体struct EVENT_T成员,因为在定义struct INPUT_EVENT的时候sizeof(struct EVENT_T)大小一定,所以在struct INPUT_EVENT{}中的成员可以是struct EVENT_T和struct EVENT_T *。
5.typedef的使用
这个关键字定义变量,结构体的用法其实并不陌生,可以考虑
-
typedef int (*FUNC)(char *,char); //定义函数指针类型FUNC
-
-
int strfind(char* str,char c) //找出str中的c的位子
-
{
-
...
-
return xx;
-
}
-
-
int main()
-
{
-
char str="asd";
-
FUNC pfind = NULL; //定义一个函数指针find
-
int sta;
-
pfind = strfind;
-
sta = pfind(str,'s'); //用函数指针pfind调用函数strfind
-
return 0;
-
}
可以考虑这个程序函数指针定义是否有问题?
6.循环链表的了解
单向链表:结构0中的next指针指向结构1的地址,结构1中的next指针指向结构2的地址,....结构N-1中的next指针指向结构N的地址;
循环链表:结构0中的next指针指向结构1的地址,结构1中的next指针指向结构2的地址,....结构N-1中的next指针指向结构N的地址,结构N中的next指针指向结构0的地址;
-
---porting_event address is:0x8049800--- //结构体0的地址
-
//循环链表
-
The Data of Link->event[0].next is = 0x0x8049810 //结构体0的next指向地址,即结构体1
-
The Data of Link->event[1].next is = 0x0x8049820 //结构体1的next指向地址,即结构体2
-
The Data of Link->event[2].next is = 0x0x8049800 //结构体2的next指向地址,即结构体0
7.内存对齐:
---sizeof(porting_event) = 76---
正如:第1点中描述的sizeof(struct EVENT_T) = 12 + 4 = 16Byte;
那么
-
typedef struct INPUT_EVENT{
-
EVENT_T event[MAX_EVENT]; //16*3
-
EVENT_T *read; //4
-
EVENT_T *write; //4
-
unsigned int cnt; //4
-
sem_t e_lock; //16
-
}INPUT_EVENT;
阅读(1405) | 评论(0) | 转发(0) |