Chinaunix首页 | 论坛 | 博客
  • 博客访问: 141486
  • 博文数量: 21
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 233
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-17 15:31
个人简介

学习中。。

文章分类

全部博文(21)

文章存档

2015年(1)

2014年(17)

2013年(3)

我的朋友

分类: C/C++

2014-07-18 16:00:34


环境:redhat5.0
编译器:GCC
      
        学习Linux得有良好的C语言基础,而C语言除了看书之外最重要的是通过项目或小例子来实践,这样有可能更深刻的理解书本上的内容。单看书不实践是没用的。
        通过下面的小例子回顾一下结构体的几点内容:
        1.结构体成员的定义
        2.结构体成员的访问
        3.结构体指针的使用
        4.结构体的嵌套定义
        5.typedef的使用
        6.循环链表的了解
        7.内存对齐

先看代码:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <semaphore.h>

  4. #define MAX_EVENT    3

  5. typedef struct EVENT_T{
  6.     int         event[3];
  7.     struct EVENT_T     *next;
  8. }EVENT_T;

  9. typedef    struct INPUT_EVENT{
  10.     EVENT_T     event[MAX_EVENT];
  11.     EVENT_T        *read;
  12.     EVENT_T        *write;
  13.     unsigned int     cnt;
  14.     sem_t         e_lock;
  15. }INPUT_EVENT;


  16. static INPUT_EVENT porting_event;

  17. int Event_Struct_Init(void)
  18. {
  19.     unsigned char i;
  20.     memset(&porting_event,0,sizeof(porting_event));
  21.     for(i = 0; i < MAX_EVENT - 1; i++)
  22.     {
  23.         porting_event.event[i].next = &porting_event.event[i + 1];
  24.     }
  25.     porting_event.event[MAX_EVENT-1].next = &porting_event.event[0];
  26.     porting_event.read = &porting_event.event[0];
  27.     porting_event.write = &porting_event.event[0];
  28.     porting_event.cnt = 0;    
  29.     
  30.     return 0;
  31. }

  32. void EVENTLink_Print(INPUT_EVENT *Link)
  33. {
  34.     unsigned char i;
  35.     for(i = 0; ((Link->event[i].next) != NULL) && (i < (MAX_EVENT)); i++)
  36.     {
  37.         //Link->event[i].next is a pointer ,next line print zhe date in pointer's memory
  38.         printf("The Data of Link->event[%d].next is = 0x%p\n",i,Link->event[i].next);
  39.         //Link->event[i].next is a pointer ,next line print zhe address of pointer's
  40.         printf("The Address of Link->event[%d].next is = 0x%x\n",i,&(Link->event[i].next));
  41.     }
  42.     printf("Print sucessful\n");
  43. }

  44. int main(int argc , char *argv[])
  45. {
  46.     int ret;
  47.     ret = Event_Struct_Init();
  48.     printf("---sizeof(porting_event) = %d---\n",sizeof(porting_event));
  49.     printf("---porting_event address is:0x%x---\n",&porting_event);
  50.     EVENTLink_Print(&porting_event);
  51.     return 0;
  52. }

点击(此处)折叠或打开

  1. [root@localhost C_Func]# gcc struct_define.c -o struct_define
  2. [root@localhost C_Func]# ./struct_define
  3. ---sizeof(porting_event) = 76---
  4. ---porting_event address is:0x8049800---
  5. The Data of Link->event[0].next is = 0x0x8049810
  6. The Address of Link->event[0].next is = 0x804980c
  7. The Data of Link->event[1].next is = 0x0x8049820
  8. The Address of Link->event[1].next is = 0x804981c
  9. The Data of Link->event[2].next is = 0x0x8049800
  10. The Address of Link->event[2].next is = 0x804982c
  11. Print sucessful





 根据开头提出的几点逐一说明:
1.结构体成员的定义:
        结构体成员的定义C语言书上讲的很详细,可以参考。这里主要讲的是定义成员时,成员的类型是结构体本身的情况。又分为下面A、B两种。
        A:成员类型是结构体本身。
        B: 成员类型是结构体指针。
        结构体的大小是在编译时决定的(实际内存分配是在定义结构体实际变量时)。

点击(此处)折叠或打开

  1. typedef struct EVENT_T{
  2.     int         event[3];
  3.     struct EVENT_T     *next;
  4. }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.结构体成员的访问

点击(此处)折叠或打开

  1. //Link->event[i].next is a pointer ,next line print zhe date in pointer's memory
  2. printf("The Data of Link->event[%d].next is = 0x%p\n",i,Link->event[i].next);       //输出next指针中的内容
  3. //Link->event[i].next is a pointer ,next line print zhe address of pointer's
  4. printf("The Address of Link->event[%d].next is = 0x%x\n",i,&(Link->event[i].next));//输出next指针本身的4字节地址//考虑  *(Link->event[i].next)的结果?
3.结构体指针的使用

点击(此处)折叠或打开

  1. void EVENTLink_Print(INPUT_EVENT *Link) //形参-指针

  2. int main(int argc,char *argv[])
  3. {
  4.     ...
  5.     EVENTLink_Print(&porting_event);   //实参-地址
  6.     ...
  7. }
4.结构体的嵌套定义

点击(此处)折叠或打开

  1. typedef struct EVENT_T{
  2.     int         event[3];
  3.     struct EVENT_T     *next;
  4. }EVENT_T;

  5. typedef    struct INPUT_EVENT{
  6.     EVENT_T     event[MAX_EVENT];
  7.     EVENT_T        *read;
  8.     EVENT_T        *write;
  9.     unsigned int     cnt;
  10.     sem_t         e_lock;
  11. }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的使用
        这个关键字定义变量,结构体的用法其实并不陌生,可以考虑

点击(此处)折叠或打开

  1. typedef int*FUNC)(char *,char);    //定义函数指针类型FUNC

  2. int strfind(char* str,char c)           //找出str中的c的位子
  3. {
  4.     ...
  5.     return xx;
  6. }

  7. int main()
  8. {
  9.     char str="asd";
  10.     FUNC pfind = NULL;                //定义一个函数指针find
  11.     int sta;
  12.     pfind = strfind;
  13.     sta = pfind(str,'s');             //用函数指针pfind调用函数strfind
  14.     return 0;
  15. }
        可以考虑这个程序函数指针定义是否有问题?

6.循环链表的了解
        单向链表:结构0中的next指针指向结构1的地址,结构1中的next指针指向结构2的地址,....结构N-1中的next指针指向结构N的地址;
        循环链表:结构0中的next指针指向结构1的地址,结构1中的next指针指向结构2的地址,....结构N-1中的next指针指向结构N的地址,结构N中的next指针指向结构0的地址

点击(此处)折叠或打开

  1. ---porting_event address is:0x8049800---           //结构体0的地址
  2. //循环链表
  3. The Data of Link->event[0].next is = 0x0x8049810    //结构体0的next指向地址,即结构体1
  4. The Data of Link->event[1].next is = 0x0x8049820    //结构体1的next指向地址,即结构体2
  5. 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;
那么

点击(此处)折叠或打开

  1. typedef    struct INPUT_EVENT{
  2.     EVENT_T     event[MAX_EVENT];        //16*3
  3.     EVENT_T        *read;                //4
  4.     EVENT_T        *write;               //4
  5.     unsigned int     cnt;                //4
  6.     sem_t         e_lock;                //16
  7. }INPUT_EVENT;







阅读(1405) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~