zoukankan      html  css  js  c++  java
  • 认识C中的结构体

      C中结构体是另外一种表示数据形式的方式,结构体中可以表示C中的基本数据形式,如int,double....结构体可以让我们更好的表示数据。下面来看看结构体。

      说到结构体首先要了解的是它的申明形式,要申明一个结构体形式如下:

     1 #include<stdio.h>
     2 #define LEN 20
     3 
     4 //申明一个结构体
     5 struct name {
     6     char firstname[LEN];
     7     char lastname[LEN];
     8 };
     9 
    10 //申明一个结构体
    11 struct guy {
    12     struct name handle;        //结构体嵌套
    13     char favfood[LEN];
    14     char job[LEN];
    15     int age;
    16 };
    17 
    18 int main(int argc, char* argv[])
    19 {
    20   ........
    21 }

      在结构体中可以有基本的数据类型例如上面的int,char数组,也可以嵌套有其他结构体,例如上面结构体guy中就存在另外一个结构体name。值得注意的是,我们在申明一个结构体的时候,计算机并没有为数据分配空间,而是在我们创建结构变量的时候才会进行分配。创建结构变量的形式如下:

     1 struct guy new_guy; 

      在计算机执行到上面这句时,计算机会为变量分配内存。如上guy中包含一个name结构体,name结构体中是由两个20个char所占字节组成,共计2*20=40字节,而favfood和job也是两个长度为20的char数组,age是一个int类型,所以一个guy类型的变量所占字节数共计为40+20+20+4=84。

      现在我们知道如何申明一个结构体和定义一个结构体变量了。先看看下面的代码:

     1 struct guy new_guy1 = { //结构体的初始化
     2         {"zhou","xuanyu"},
     3         "tomato",
     4         "student",
     5          22
     6     };
     7 struct guy new_guy2 = { //结构体的初始化
     8         .handle = {"zhou","xuanyu"},
     9         .job = "student",
    10     };

      上面一段代码是对一个结构体进行初始化,对于new_guy1,我们对它的每一个属性都初始化了,而对于new_guy2我们仅仅初始化了他的handle和job。对于一个结构体我们应该怎么访问结构体中的每一个项呢?不错,是使用 . 运算符。例如:

     1 printf("%s",new_guy2.handle); ,就可以打印出"zhouxuanyu"。再看看下面这段代码(其中的结构体guy在上面已定义):

     1 int main(int argc, char* argv[])
     2 {
     3     struct guy new_guy[2] = {    //定义一个结构体数组
     4         {
     5             {"zhou","xuanyu"},"tomato","student",22    //初始化数组第一项
     6         },
     7         {
     8             {"hu","jiannan"},"fruit","student",22    //初始化数组第二项
     9         }
    10     };
    11     
    12     struct guy * him; //指向结构体guy的指针
    13     him = &new_guy[0]; //将指针指向guy数组
    14     
    15     printf("address #1:%p, #2:%p
    ",&new_guy[0],&new_guy[1]);
    16     printf("pointer #1:%p, #2:%p
    ",him,him+1);
    17     
    18     printf("him->handle.firstname is %s,(*him).age is %d
    ",him->handle.firstname,(*him).age);
    19     him++;
    20     printf("him->job is %s,(*him).handle.lastname is %s
    ",him->job,(*him).handle.lastname);
    21 }

      在上面这段代码中,我们定义了一个guy类型的数组,定义一个结构体数组的形式和定义一般数组一样。在上面代码第12行中我们申明了一个指向结构体的指针him,利用指针我们可以对数据的操作会更加灵活。在13行,我们初始化了这个指针,这里要注意的是结构体的名称和数组名不同,数组名就是数组其实元素的地址,所以可以这样做int *p = a,假设a是一个int类型的数组,但是结构体不行,必须使用&取地址。所用上面15,16行打印出来的地址是一样的。上面的代码中又出现了一个新的运算符->。它的作用和刚刚说的 . 运算符一样,只是作用的对象不一样,简单的记法就是:指针使用->访问结构体中的项,而结构体变量使用.访问它的项。到现在我们已经大概了解了结构体的基本用法。下面来看看结构体在函数中使用的几种方式:

     1 #include<stdio.h>
     2 #define LEN 20
     3 
     4 struct Book {                 //定义结构体
     5     char bookname[LEN];
     6     double price;
     7     char author[LEN];
     8 };
     9 
    10 //三个函数都用于改变书的价格
    11 double changebook1(double);        //因为只改变书的价格,直接将价格作为参数传入函数
    12 double changebook2(struct Book *);    //传入一个指向Book类型的指针
    13 double changebook3(struct Book);    //传入一个结构体
    14 
    15 
    16 int main(int argc, char* argv[])
    17 {
    18     struct Book book = {
    19         "C Primer Plus",75.0,"John"
    20     };
    21     
    22     struct Book * p_book = &book;
    23     
    24     printf("book's price is: %f
    ",book.price);
    25     printf("after changebook1(),return value is: %.2f, book's price is: %.2f
    ",changebook1(book.price),book.price);
    26     double new_price2 = changebook2(p_book);
    27     printf("after changebook2(),return value is: %.2f, book's price is: %.2f
    ",new_price2,book.price);
    28     double new_price3 = changebook3(book);
    29     printf("after changebook3(),return value is: %.2f, book's price is: %.2f
    ",new_price3,book.price);
    30 }
    31 
    32 double changebook1(double price){
    33     return price * 2;
    34 }
    35 
    36 double changebook2(struct Book * book){
    37     book->price *= 2;
    38     return book->price;
    39 }
    40 
    41 double changebook3(struct Book book){
    42     book.price *= 4;
    43     return book.price;
    44 }

      上面的代码中,我们定义了三个函数用来改变book的价格,第一个是直接将double类型的pirce传入,第二个是将一个指向结构体的指针传入,第三个是将整个结构体传入。最后打印出函数运行之后的结构,如下:

      

      从结果可以看出,只有changebook2()函数才真正的将书的价格改变了。这是为什么呢?原因是这样的,方法二是将一个指针作为参数传入函数,指针指向的是原始数据,所以我们所做的所有操作都是在原始数据上进行的。而方法三传入的是一个结构体,在调用函数changebook3()的时候,会根据模板Book创建一个自动变量,然后这个变量的成员会被初始化与原始数据一样副本。而我们所进行的操作都是在这个副本上进行的,所以不会对原始数据有任何改变。但是这样的做法会对内存有很大的浪费,所以我们一般使用的第二种方式,但是第二种方式会有破坏数据的可能,该怎么办呢?在C中const关键字可以解决这个问题。如果我们对原始数据不需要进行修改,这时候可以将传入函数的指针用const修饰。

  • 相关阅读:
    动态规划:POJ2576-Tug of War(二维费用的背包问题)
    动态规划:HDU3496-Watch The Movie(二维费用的背包问题)
    动态规划:HDU1712-ACboy needs your help(分组背包问题)
    水题:HDU1303-Doubles
    动态规划:HDU2844-Coins(多重背包的二进制优化)
    动态规划:HDU1059-Dividing(多重背包问题的二进制优化)
    动态规划:HDU1224-Free DIY Tour
    动态规划:HDU1864-最大报销额(处理带小数的dp问题)
    红黑树
    二叉树
  • 原文地址:https://www.cnblogs.com/zhouxuanyu/p/4512944.html
Copyright © 2011-2022 走看看