认识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\n",&new_guy[0],&new_guy[1]);
16     printf("pointer #1:%p, #2:%p\n",him,him+1);
17
18     printf("him->handle.firstname is %s,(*him).age is %d\n",him->handle.firstname,(*him).age);
19     him++;
20     printf("him->job is %s,(*him).handle.lastname is %s\n",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\n",book.price);
25     printf("after changebook1(),return value is: %.2f, book‘s price is: %.2f\n",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\n",new_price2,book.price);
28     double new_price3 = changebook3(book);
29     printf("after changebook3(),return value is: %.2f, book‘s price is: %.2f\n",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修饰。

时间: 2024-11-03 21:54:38

认识C中的结构体的相关文章

关于c语言中的结构体使用偏移量求值问题

最近在看nginx源码,看到定时器的时候,发现一个结构体利用偏移量求值问题, 结构体相信做c开发的都遇到过,那么不知你对结构体中成员变量偏移这块是如何理解的; 首先我们先看一下nginx中的那个让我迷惑的地方 ev =    (event_t*)((char*)node - offsetof(event_t, timer)); 这里,可以得知道是利用event_t结构体的timer变量,来反求event_t结构体的地址 说明一下: event_t是一个结构体 node 也是一个结构体 timer

[转]C#中的结构体与类的区别

C#中的结构体与类的区别 经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字class 定义结构使用关键字struct.在语法上其实类和结构有着很多相似的地方. 定义类的语法 1 class Person 2 { 3 private string name; 4 private int age; 5 6 public void SayHi() 7 { 8 Console.WriteL

C语言中的结构体和C++中的结构体以及C++中类的区别

c++中结构体可以定义一个函数 C中的结构体和C++中结构体的不同之处:在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数. C++中的结构体和类的异同: 一.相同之处:结构体中可以包含函数:也可以定义public.private.protected数据成员:定义了结构体之后,可以用结构体名来创建对象.但C中的结构体不允许有函数:也就是说在C++当中,结构体中可以有成员变量,可以有成员函数,可以从别的类继承,也可以被别的类继承,可以有虚函数. 二.不同之处

C语言中的结构体,结构体数组

C语言中的结构体是一个小难点,下面我们详细来讲一下:至于什么是结构体,结构体为什么会产生,我就不说了,原因很简单,但是要注意到是结构体也是连续存储的,但要注意的是结构体里面类型各异,所以必然会产生内存对齐的问题.也就是内存里面会有空档. 1.结构体的定义和赋值 结构体是可以直接初始化的,在定义的时候,就可以初始化,而且如果你的结构体中恰好有字符数组的话,这个时候初始化是不错的选择,原因很简单,字符数组只能定义的时候直接初始化 后来就不可以了,后来你就只能用strcpy函数来拷贝初始化了. str

C++中的结构体

http://zhidao.baidu.com/link?url=8OYQSKV9mvSBc6Hkf9NsLQmipSge9VCZDJQGAZZs5PCBQ54UTmK98VRmAklEEAFYu7dHi9yhLhWeLsP4EwFW5_ c++中结构体可以定义一个函数 C中的结构体和C++中结构体的不同之处:在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数. C++中的结构体和类的异同: 一.相同之处:结构体中可以包含函数:也可以定义public.pr

黑马程序员-------oc中的结构体

oc中的结构体主要有CGPoint,CGSize,CGRect,NSRange; /* Points. */ struct CGPoint { CGFloat x; CGFloat y; }; typedef struct CGPoint CGPoint; /* Sizes. */ struct CGSize { CGFloat width; CGFloat height; }; /* Rectangles. */ struct CGRect { CGPoint origin; CGSize s

浅析C#中的结构体和类

类和结构是 .NET Framework 中的常规类型系统的两种基本构造. 两者在本质上都属于数据结构.封装着一组总体作为一个逻辑单位的数据和行为. 数据和行为是该类或结构的"成员",它们包括各自的方法.属性和事件等 对于C/C++程序员来说.结构体和类的差别非常小.仅仅是结构体的默认成员变量为public,类的默认成员变量为private. 可是对于C#来说,结构体和类有非常多的不同. 首先来谈一谈为何须要结构体: 最主要的原因就是结构体有能力去管理.使用不同数据类型的组合. .NE

x264中重要结构体参数解释,参数设置,函数说明 &lt;转&gt;

x264中重要结构体参数解释http://www.usr.cc/thread-51995-1-3.htmlx264参数设置http://www.usr.cc/thread-51996-1-3.html x264中重要结构体参数解释typedef struct x264_param_t{/* CPU 标志位 */unsigned int cpu;int         i_threads;       /* 并行编码多帧 */int         b_deterministic; /*是否允许非

C++中的结构体,C管理进程代码,C++管理进程代码,C语言中的联合体

 1.C++中的结构体 #include<iostream> struct lstruct { int num; }; struct MyStruct { int num; double db = 10.8;//可以有默认的值 //MyStruct sx;//拒绝内部定义自己,也就是说不能够内部指向自己 MyStruct *pnext; MyStruct *phead; lstruct  l1; void boss()  //可以有方法 { } }; struct MyStructA {

再识C中的结构体

在前面认识C中的结构体中我介绍了结构体的基础知识,下面通过这段代码来回顾一下: 1 #include<stdio.h> 2 #define LEN 20 3 4 struct Student{ //定义结构体 5 char name[LEN]; 6 char address[LEN]; 7 int age; 8 }; 9 10 int main(int argc, char* argv[]) 11 { 12 struct Student s = { //初始化 13 "bluemsu