C语言 
    
  
 
  结构体 
 
结构 
结构式C语言中一种用户自定义的可用的数据类型,允许存储不同的数据项
结构体中的数据成员可以是基本数据结构,也可以是其他结构体类型,甚至是指针类型
声明结构体:struct 结构体名 { 数据成员声明; } 
结构体的声明由关键词struct和结构体的名称组成,结构体名称是自行定义的
并且结构体的声明可以在main函数之外,可以作为全局的一个变量
当然,也可以在main里面定义,但是出了函数之后就不能使用了
C struct   student   { 
     char   name [ 20 ]; 
     int   age ; 
     float   score ; 
} student1 ,   student2 ; 
这个student是结构体标签,表示定义了一种新的结构体数据结构,其中这种数据结构中包括了三个变量,分别是name、age和score
然后我们在定义完结构体之后,在}后面;之前声明了我们想要的结构体变量,这里我们声明了两个student结构体变量student1和student2
一般情况下,结构体标签,内部变量的声明和结构体变量的声明三个至少出现两个
其他写法
没有直接声明变量 
 
C //此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c 
//结构体的标签被命名为SIMPLE,没有声明变量 
struct   SIMPLE 
{ 
     int   a ; 
     char   b ; 
     double   c ; 
}; 
//用SIMPLE标签的结构体,另外声明了变量t1、t2、t3 
struct   SIMPLE   t1 ,   t2 [ 20 ],   * t3 ; 
没有标签 
 
C //此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c 
//同时又声明了结构体变量s1 
//这个结构体并没有标明其标签 
struct 
{ 
     int   a ; 
     char   b ; 
     double   c ; 
}   s1 ; 
使用typedef创造新类型 
 
C //也可以用typedef创建新类型 
typedef   struct 
{ 
     int   a ; 
     char   b ; 
     double   c ; 
}   Simple2 ; 
//现在可以用Simple2作为类型声明新的结构体变量 
Simple2   u1 ,   u2 [ 20 ],   * u3 ; 
不直接声明标签的结构体即使内部成员和声明了标签的另外一个结构体完全一样,编译器也会把这两个当做是不同的类型
结构体的成员也可以包含其他结构体,特可以包含指向自己结构体类型的指针,而通常这种指针的应用是为了更加高级的数据结构比如链表和树
C //此结构体的声明包含了指向自己类型的指针 
struct   NODE 
{ 
     char   string [ 100 ]; 
     struct   NODE   * next_node ; 
}; 
我们暂时不考虑这些互相包含的结构体
结构体的初始化 
C      #include   <stdio.h> 
     struct   Books 
     { 
     char    title [ 50 ]; 
     char    author [ 50 ]; 
     char    subject [ 100 ]; 
     int     book_id ; 
     }   book   =   { "C 语言" ,   "C" ,   "编程语言" ,   123456 }; 
     int   main () 
     { 
         printf ( "title : %s \n author: %s \n subject: %s \n book_id: %d \n " ,   book . title ,   book . author ,   book . subject ,   book . book_id ); 
     } 
也可以直接赋值,通过我们最熟悉的scanf函数来输入结构体变量的值
Bash 7 -1  计算职工工资
  15 
  C课程组
  浙江大学
= 基本工资+浮动工资-支出)。
  基本工资  浮动工资  支出”,中间以空格分隔。
3 
  240   400   75 
  360   120   50 
  560   150   80 
  565 .00
  430 .00
  630 .00
C #include <stdio.h> 
struct   inf { 
     char   s [ 10 ]; 
     double   mon ; 
     double   temp ; 
     double   pay ; 
}; 
int   main (){ 
     int   n ; 
     scanf ( "%d \n " , & n ); 
     struct   inf   name [ n ]; 
     for ( int   i   =   0 ; i   <   n ; i ++ ){ 
         scanf ( "%s %lf %lf %lf \n " , name [ i ]. s , & name [ i ]. mon , & name [ i ]. temp , & name [ i ]. pay ); 
     } 
     for ( int   i   =   0 ; i   <   n ; i ++ ){ 
         double   sum   =   name [ i ]. mon + name [ i ]. temp - name [ i ]. pay ; 
         printf ( "%s %.2f \n " , name [ i ]. s , sum ); 
     } 
     return   0 ; 
} 
结构体的访问 
成员访问运算符.
C #include   <stdio.h> 
#include   <string.h> 
struct   Books 
{ 
    char    title [ 50 ]; 
    char    author [ 50 ]; 
    char    subject [ 100 ]; 
    int     book_id ; 
}; 
int   main (   ) 
{ 
    struct   Books   Book1 ;          /* 声明 Book1,类型为 Books */ 
    struct   Books   Book2 ;          /* 声明 Book2,类型为 Books */ 
    /* Book1 详述 */ 
    strcpy (   Book1 . title ,   "C Programming" ); 
    strcpy (   Book1 . author ,   "Nuha Ali" );   
    strcpy (   Book1 . subject ,   "C Programming Tutorial" ); 
    Book1 . book_id   =   6495407 ; 
    /* Book2 详述 */ 
    strcpy (   Book2 . title ,   "Telecom Billing" ); 
    strcpy (   Book2 . author ,   "Zara Ali" ); 
    strcpy (   Book2 . subject ,   "Telecom Billing Tutorial" ); 
    Book2 . book_id   =   6495700 ; 
    /* 输出 Book1 信息 */ 
    printf (   "Book 1 title : %s \n " ,   Book1 . title ); 
    printf (   "Book 1 author : %s \n " ,   Book1 . author ); 
    printf (   "Book 1 subject : %s \n " ,   Book1 . subject ); 
    printf (   "Book 1 book_id : %d \n " ,   Book1 . book_id ); 
    /* 输出 Book2 信息 */ 
    printf (   "Book 2 title : %s \n " ,   Book2 . title ); 
    printf (   "Book 2 author : %s \n " ,   Book2 . author ); 
    printf (   "Book 2 subject : %s \n " ,   Book2 . subject ); 
    printf (   "Book 2 book_id : %d \n " ,   Book2 . book_id ); 
    return   0 ; 
} 
用结构体.成员的方式访问结构体的成员,直接调用了变量,可以进行复制,取值等操作,和别的变量没有其他区别
作为函数参数被传入传出 
C #include   <stdio.h> 
#include   <string.h> 
struct   Books 
{ 
    char    title [ 50 ]; 
    char    author [ 50 ]; 
    char    subject [ 100 ]; 
    int     book_id ; 
}; 
/* 函数声明 */ 
void   printBook (   struct   Books   book   ); 
int   main (   ) 
{ 
    struct   Books   Book1 ;          /* 声明 Book1,类型为 Books */ 
    struct   Books   Book2 ;          /* 声明 Book2,类型为 Books */ 
    /* Book1 详述 */ 
    strcpy (   Book1 . title ,   "C Programming" ); 
    strcpy (   Book1 . author ,   "Nuha Ali" );   
    strcpy (   Book1 . subject ,   "C Programming Tutorial" ); 
    Book1 . book_id   =   6495407 ; 
    /* Book2 详述 */ 
    strcpy (   Book2 . title ,   "Telecom Billing" ); 
    strcpy (   Book2 . author ,   "Zara Ali" ); 
    strcpy (   Book2 . subject ,   "Telecom Billing Tutorial" ); 
    Book2 . book_id   =   6495700 ; 
    /* 输出 Book1 信息 */ 
    printBook (   Book1   ); 
    /* 输出 Book2 信息 */ 
    printBook (   Book2   ); 
    return   0 ; 
} 
void   printBook (   struct   Books   book   ) 
{ 
    printf (   "Book title : %s \n " ,   book . title ); 
    printf (   "Book author : %s \n " ,   book . author ); 
    printf (   "Book subject : %s \n " ,   book . subject ); 
    printf (   "Book book_id : %d \n " ,   book . book_id ); 
} 
传入的可以是结构体变量,也可以把内部成员作为变量传出去.
结构体指针 
定义一个指向结构的指针,方式与定义指向其他类型变量的指针类似
可以在上面的变量中存储Books型结构变量的地址
这样ptr就指向Book1结构变量的地址
为了使用指向该结构的指针访问结构的成员,必须使用->运算符
这样就把Book1的title成员的值改为C 语言
结构体大小的计算 
sizeof运算符可以计算结构体的大小,返回的事结构体的总字节数,包括所有成员变量的大小以及可能的填充字节
C #include   <stdio.h> 
struct   Person   { 
     char   name [ 20 ]; 
     int   age ; 
     float   height ; 
}; 
int   main ()   { 
     struct   Person   person ; 
     printf ( "结构体 Person 大小为: %zu 字节 \n " ,   sizeof ( person )); 
     return   0 ; 
} 
输出:
注意
结构体的大小可能会受到编译器的优化和对齐规则的影响,编译器可能会在结构体中插入一些额外的填充字节以对齐结构体的成员变量,以提高内存访问效率。因此,结构体的实际大小可能会大于成员变量大小的总和
 
结构体数组 
Tips
结构体也可以定义为数组,数组中每个元素都是一个结构体变量
 
这样books数组中有10个Books结构体变量
数组的下标从0开始,可以用books[i]的方式访问数组中的元素
C books [ 0 ]. title   =   "C 语言" ; 
books [ 0 ]. author   =   "C" ; 
books [ 0 ]. subject   =   "编程语言" ; 
books [ 0 ]. book_id   =   123456 ; 
这样就把books[0]的title成员的值改为C 语言
HW9好题 
Bash 7 -9  值班安排
  50 
  张泳
  浙大城市学院
  7位大夫,在一星期内(星期一至星期天)每人要轮流值班一天,如果已知:
( 2 ) 直接显示了D与E间的关系,而通过条件(1)、(6)、(5)可以间接得到A与B的关系。
  比较运算符  编号  天数
  或  <  ,分别表示“早”或“晚”
   表示:A大夫比C大夫晚1天值班
  =   数值
= 4    表示:F大夫在星期四值班
7 
F = 4 
C #include <stdio.h> 
struct   condition { 
     int   obj1 ; //用于存储输入的第一个字母- 'A'的值  
     int   obj2 ; //存储第二个字母的  
     int   num ; //存储数字  
     int   ret ; //是否是 =   
} condition [ 20 ]; 
int   judge ( int   * a , int   n );      //判断函数  
int   main ( void ) 
{ 
     int   n ; 
     scanf ( "%d \n " , & n ); 
     int   i ; 
     char   s [ 5 ]; 
     //录入数据  
     for ( i = 0 ;   i < n ;   i ++ ){ 
         gets ( s ); 
         condition [ i ]. obj1   =   s [ 0 ]   -   'A' ; 
         if ( s [ 1 ]   !=   '=' ){ 
             condition [ i ]. obj2   =   s [ 2 ]   -   'A' ; 
             condition [ i ]. num   =   s [ 3 ]   -   '0' ; 
             condition [ i ]. ret   =   0 ;         //如果输入的不是 = 就ret录为1;         
         } 
         else { 
             condition [ i ]. num   =   s [ 2 ]   -   '0' ;    
             condition [ i ]. ret   =   1 ; 
         } 
         if ( s [ 1 ]   ==   '<' ){ 
             condition [ i ]. num   *=   -1 ;       //如果是 < 存储的数字变为负;  
         } 
     } 
     //循环给数组赋值 0~6各种情况,在给判断函数判断是否符合输入的条件。  
     int   day [ 7 ]   ;      //值班顺序 ,下标表示 ABCDEFG,对应值表示时间。  
     int   a , b , c , d , e , f , g ; 
     for ( a = 0 ;   a < 7 ;   a ++ ){ 
         for ( b = 0 ;   b < 7   ;   b ++ ){ 
             for ( c = 0 ;   c < 7   ;   c ++ ){ 
                 for ( d = 0 ;   d < 7   ;   d ++ ){ 
                     for ( e = 0 ;   e < 7   ;   e ++ ){ 
                         for ( f = 0 ;   f < 7   ;   f ++ ){ 
                             for ( g = 0 ;   g < 7   ;   g ++ ){ 
                                 day [ 0 ]   =   a ; 
                                 day [ 1 ]   =   b ; 
                                 day [ 2 ]   =   c ; 
                                 day [ 3 ]   =   d ; 
                                 day [ 4 ]   =   e ; 
                                 day [ 5 ]   =   f ; 
                                 day [ 6 ]   =   g ; 
                                 if ( judge ( day , n ))      //判断是否符合输入的条件。  
                                     goto   E ; 
                             } 
                         } 
                     } 
                 } 
             } 
         } 
     } 
E :    
     if ( judge ( day , n )){ 
         char   Day [ 8 ]; 
         for ( i = 0 ;   i < 7 ;   i ++ ){ 
             Day [ day [ i ]]   =   i   +   'A' ;    //把值班时间按顺序写入对应大夫  
         } 
         Day [ 8 ]   =   '\0' ; 
         puts ( Day ); 
     } 
     return   0 ; 
} 
int   judge ( int   * a , int   n ){ 
     int   i   =   0 ; 
     int   ret   =   1 ; 
     //判断传入的值班日期与输入的条件是否符合。  
     for ( i = 0 ;   i < n ;   i ++ ) 
     { 
         //如果是 = ,就判断值班日期和条件日期-1是否相等 .(值班日期是从0开始算的)  
         if ( condition [ i ]. ret ){ 
             if ( a [ condition [ i ]. obj1 ]   !=   condition [ i ]. num   -   1 ) 
                 ret   =   0 ; 
                 break ; 
         }   
         else   if ( a [ condition [ i ]. obj1 ]   +   condition [ i ]. num   !=   a [ condition [ i ]. obj2 ]){ 
             ret   =   0 ; 
             break ; 
         } 
     } 
     return   ret ; 
} 
Bash 7 -8  停车场管理
  50 
  张泳
  浙大城市学院
  ( 即最先到达的第一辆车停放在停车场的最里面)   。如果停车场已放满n辆车,则以后到达的车辆只能在停车场大门外的便道上等待,一旦停车场内有车开走,则排在便道上的第一辆车可以进入停车场。停车场内如有某辆车要开走,则在它之后进入停车场的车都必须先退出停车场为它让路,待其开出停车场后,这些车辆再依原来的次序进场。每辆车在离开停车场时,都应根据它在停车场内停留的时间长短交费,停留在便道上的车不收停车费。编写程序对该停车场进行管理。
( n<= 10 ) ,再输入若干组数据,每组数据包括三个数据项:汽车到达或离开的信息(A表示到达、D表示离开、E表示结束)、汽车号码、汽车到达或离开的时刻。
  car  not  in   park
3 
  1   1   
  2   2 
  3   3 
  1   4 
  4   5 
  5   6 
  4   7 
  5   8 
  0   0 
  in   parking  space  #1 
  in   parking  space  #2 
  in   parking  space  #3 
  out,parking  time   3 
  in   parking  space  #3 
  waiting
  out,parking  time   2 
  in   parking  space  #3 
  out,parking  time   1 
C #include   <stdio.h> 
typedef   struct   CAR { 
     char   zt ; 
     int   num ; 
     int   in ; 
} car ; 
int   main () 
{ 
     int   n ; 
     scanf ( "%d" , & n ); 
     int   space = 1 , xb ; 
     car   a [ 100 ]; 
     int   last , wait = -1 , k = 0 , flag , f ; 
     do { 
         scanf ( "%c %d %d" , & a [ k ]. zt , & a [ k ]. num , & a [ k ]. in ); 
         if ( a [ k ]. zt != 'E' ) k ++ ; 
     } while ( a [ k ]. zt != 'E' ); 
     for ( int   i = 0 ; i < k ; i ++ ){ 
         if ( a [ i ]. zt == 'E' ){ 
             break ; 
         } else   if ( a [ i ]. zt == 'A' ){ 
             if ( space != n + 1 ){ 
                 printf ( "car#%d in parking space #%d \n " , a [ i ]. num , space ); 
                 space ++ ; 
             } else { 
                 printf ( "car#%d waiting \n " , a [ i ]. num ); 
                 wait = a [ i ]. num ; 
             } 
         } else   if ( a [ i ]. zt == 'D' ){ 
             f = 0 ; 
             flag = a [ i ]. in ; 
             for ( int   j = 0 ; j < i ; j ++ ){ 
                 if ( a [ i ]. num == a [ j ]. num ){ 
                     f = 1 ; 
                     last = a [ i ]. in - a [ j ]. in ; 
                     break ; 
                 } 
             } 
             if ( f ){ 
             printf ( "car#%d out,parking time %d \n " , a [ i ]. num , last ); 
             //此处将离开停车场的号码设置为不作处理的号码 
             for ( int   p = 0 ; p < k ; p ++ ){ 
                 if ( a [ p ]. num == a [ i ]. num ){ 
                     a [ p ]. num = -1 ; 
                 } 
             } 
             space -- ; 
             if ( wait != -1 ){ 
                 for ( int   j = 0 ; j < k ; j ++ ){ 
                 if ( wait == a [ j ]. num && a [ j ]. zt == 'A' ){ 
                     a [ j ]. in = flag ; 
                     break ; 
                 } 
                 } 
                 printf ( "car#%d in parking space #%d \n " , wait , space ); 
                 wait = -1 ; 
             } 
             } else { 
                 printf ( "the car not in park \n " ); 
             }     
         } 
     } 
} 
HW10边写边整理 
链表的结构 
header:头指针 
若干节点,包括数据域和指针域,最后一个节点的指针域指向空 
 
实现原理:头指针指向链表的第一个节点,然后第一个节点的指针指向下一个节点,然后以此指向最后一个节点,这样就形成了一个链表
链表的数据结构 
C struct   Node { 
     int   data ; 
     struct   Node   * next ; 
}; 
本质上是一个结构体,包括数据域和指针域
然后我们通过改变data的类型就可以存储不同的数据了
创建链表 
C #include   <stdio.h> 
#include   <stdlib.h> 
#include   <string.h> 
struct   list_node   { 
     int   data ;             // 数据域:存储整数数据 
     struct   list_node   * next ;    // 指向下一个节点的指针 
}; 
int   main ( void ) 
{ 
     struct   list_node   * node   =   NULL   ;            // 定义一个头指针 
     node   =   ( struct   list_node   * ) malloc ( sizeof ( struct   list_node ));    // 分配内存给一个 list_node 类型的节点 
     if   ( node   ==   NULL )   { 
         printf ( "malloc fail! \n " );    // 如果分配失败,输出错误信息 
         return   1 ;    // 提前退出 
     } 
     memset ( node ,   0 ,   sizeof ( struct   list_node ));   // 初始化节点数据为0 
     node -> data   =   100   ;                       // 给链表节点的数据赋值为 100 
     node -> next   =   NULL   ;                      // 将链表的指针域指向 NULL,表示链表的尾部 
     printf ( "%d \n " ,   node -> data );              // 输出链表节点的数据 
     free ( node );                              // 释放分配的内存 
     return   0   ; 
} 
从node = (list_node *)molloc(sizeof(list_node))这行代码可以看出,我们通过malloc函数申请了一块内存空间,然后将其转换为list_node类型的指针,并将其初始化为0。
其中(list_node *)是强制类型转换,将malloc函数返回的指针转换为list_node类型的指针。
这个指针指向的就是分配的那块内存空间的地址
之后我们再赋值,赋值完之后,我们再将指针域指向
然后输出print一下,最后释放掉内存空间
提炼一下分为这么几步
定义结构体来表示链表的这个结构 
定义头指针 
将头指针指向我们申请的内存空间 
然后给我们有的内存空间赋值 
最后将我们的指针指向空,等待下一个链表节点 
清空我们的链表结构体,free掉内存空间 
return 0 ; 
 
遍历链表 
C void   traverse (){ 
     struct   Node   * temp   =   head ; 
     while ( temp !=   NULL ){ 
         printf ( "%d " , temp -> data ); 
         temp   =   temp -> next ; 
     } 
     printf ( " \n " ); 
} 
删除节点 
C void   delete ( int   data ){ 
     struct   Node   * temp   =   head ; 
     struct   Node   * prev   =   NULL ; 
     while ( temp !=   NULL   &&   temp -> data !=   data ){ 
         prev   =   temp ; 
         temp   =   temp -> next ; 
     } 
     if ( temp   ==   NULL ){ 
         printf ( "Node not found \n " ); 
     } else { 
         if ( prev   ==   NULL ){ 
             head   =   temp -> next ; 
         } else { 
             prev -> next   =   temp -> next ; 
         } 
         free ( temp ); 
     } 
}