C语言程序设计——结构体

  • Post author:
  • Post category:其他


为什么要有结构体的存在??

我们在描述数据的时候我们会用到例如:

Int、float、double、long int、longlongint、char、*等数据类型来给我们的变量进行命名。

当我们在进行一些功能的编写的时候。我们会发现我们要去描述一些具体的事物的时候,使用char int等数据类型,不能满足我们的功能需求。因此C语言提供了自定义结构体关键字struct


结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合。

怎么使用struct关键字?

举一个具体例子:通过C语言来描述一本书

#include<stdio.h>

 struct BOOK
{
   const char *id;
   const char *name;
   int price;
};
int  main()
{
    BOOK book;
    book.id="1927502011";
    book.name="一千零一夜";
    book.price=19;
    printf("编号:%s\n书名:%s\n价格:%d\n",book.id,book.name,book.price);
	return 0;
}

通过struct 关键字我们可以自己定义数据类型,同时我们可以通过

typedef 来对我们的BOOK类型取别名,出来BOOK以外我们还可以使用book来定义类型,结构体是一样的。

#include<stdio.h>

 typedef struct BOOK
{
   const char *id;
   const char *name;
   int price;
}book;

结构体的嵌套

#include<stdio.h>
#include<string.h>
#pragma warning(disable:4996)
 struct BOOK
{
   char id[20];//编号
   char name[20];//姓名
   int price;//价格
 };
 struct BOOK2 {
	 BOOK book;//引用结构体BOOK 获得和BOOK一样的结构体空间
	 int nums;//库存
 };
int main()
{
	BOOK2 book2;
	strcpy(book2.book.id, "123456");
	strcpy(book2.book.name, "songchi");
	book2.book.price = 20;
	book2.nums = 100;
	printf("book2.id:%s\nbook2.name:%s\nbook2.price:%d\nbook2.nums:%d\n",book2.book.id,book2.book.name,book2.book.price,book2.nums);
	return 0;
}

我又定义了一个新的结构体叫做BOOK2,那么BOOK2拥有和BOOK一样的结构的同时,拥有nums成员,因为在结构体中定义了 BOOK book 所以BOOK2才能拥有自身nums成员的同时,拥有和BOOK一样的结构体。


结构体变量赋值问题



概念:

结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合。



语法:



struct 结构体名{










成员列表



}结构体名列表;



功能:

自定义BOOK类型的数据类型,其中有三个成员分别为id、name、price,其含义为:编号、书名和价格。在主函数中定义一个BOOK类型变量,对其成员进行赋值并且输出。



初始代码:


#include


<stdio.h>


#include


<string.h>


#pragma


warning


(


disable


:4996)


struct


BOOK


{


char


id;


char


name;


int


price;


}


;


int


main(


){


BOOK book;


book.id =


“100


1





;


book.name =





一千零一夜





;


book.price=20;


printf(


“编号:%s\n书名:%s\n价格:%d\n”


, book.id, book.name, book.price);


return 0;


}




错误:



  1. 字符串赋值方式不对

  2. BOOK定义id、name类型不合适


修改方案1



修改:


  1. id 类型修饰符修改为const char *

  2. name 类型修饰符修改为const char *



代码:


#include


<stdio.h>


#include


<string.h>


#pragma


warning


(


disable


:4996)


struct


BOOK2


{


const


char


* id;


const


char


*name;


int


price;


};


int


main() {


BOOK2


book;


book.id =


“1001”


;


book.name =


“一千零一夜”


;


book.price = 20;


printf(


“编号:%s\n书名:%s\n价格:%d\n”


, book.id, book.name, book.price);


return


0;


}



解释:


重新定义的类型是


只读字符指针


类型。在book.id进行字符串

“100


1




操作时,首先


存储变量





字符指针


,所以存储的值只能是


地址类型


。变量修饰符const char * 的


基类型





char


类型,因此在进行赋值操作的时候,并不能,也不会将


字符串


赋值进去,因为char类型作为


字符类型


,只能存储


一个字符类型数据


,且在C语言中


只存在字符变量不存在字符串变量


。在执行

book.id =


“100


1





;


语句的时候,编译系统会将字符串的




第一个字符的地址存储到字符指针变量当中去




,通过第一个字符的地址获取整个字符串。赋值语句:


book.id =


“100


1





;


的右值


“100


1




是一个常量,因为

常量指针

指向的数据是常量,


所以我们在修改数据的时候并不能通过指针去修改常量中的值,只能通过修改指针指向的常量来修改值



修改方案2



功能:

自定义BOOK类型的数据类型,其中有三个成员分别为id、name、price,其含义为:编号、书名和价格。在主函数中定义一个BOOK类型变量,对其成员进行赋值并且输出。



分析:

修改方案1中将类型修饰符修改为


只读字符指针类


型,


只读字符指针只能获取字符串第一个字符的首地址来获取整个字符串


,这样的好处是字符串


长度灵活


,坏处是


只能通过修改字符指针指向的变量来修改值


。那么我们有没有更好的解决方案呢?当然有,我们在对比id、name两个我们需要用到字符串的两个成员进行实际分析。书籍编号长度一般为固定长度,不会随意修改。书籍的名称也不会是无限长。因此我们在对这两个成员进行类型修饰的时候我们就可以使用


字符数组


来存储数据,其优点在于,


字符数组可以通过直接修改字符变量值来修改


。因此自定义结构体,我们对其成员类型修饰的时候应首先分析其实际意义,然后再决定该成员的类型。



代码:


#include


<stdio.h>


#include


<string.h>


#pragma


warning


(


disable


:4996)


struct


BOOK3


{


char


id[20];


char


name[20];


int


price;


};


int


main() {


BOOK3


book;


strcpy(book.id,


“10001”


);


strcpy(book.name,


“一千零一夜”


);


book.price = 20;


printf(


“编号:%s\n书名:%s\n价格:%d\n”


, book.id, book.name, book.price);


return


0;


}








结构体的嵌套



意义:

我们在自己创建一些结构体的时候,我们会发现有时候我们自己创建的结构体和之前创建过的结构体成员类型是一样的,那么这个时候我们就可以通过在结构体里面嵌套进结构体的方式,减少我们的代码量。



代码



#include


<stdio.h>


#include


<string.h>


#pragma


warning


(


disable


:4996)


struct


BOOK


{


char


id[20];


//编号


char


name[20];


//姓名


int


price;


//价格


};


struct


BOOK2


{


BOOK


book;


//引用结构体BOOK 获得和BOOK一样的结构体空间


int


nums;


//库存


};


int


main()


{


BOOK2


book2;


strcpy(book2.book.id,


“123456”


);


strcpy(book2.book.name,


“songchi”


);


book2.book.price = 20;


book2.nums = 100;


printf(


“book2.id:%s\nbook2.name:%s\nbook2.price:%d\nbook2.nums:%d\n”


,book2.book.id,book2.book.name,book2.book.price,book2.nums);


return


0;


}




解析:




举上面这个例子来说,我们首先创建了结构体BOOK,在使用的过程中,我们发现我们需要创建一个新的结构体来修饰我们的变量。于是创建了结构体BOOK2,BOOK2的成员是有编号、姓名、价格、库存,可以发现BOOK2的成员和BOOK的成员基本一致,仅仅是在BOOK的基础上新增了库存成员,如果不是使用结构体嵌套的话我们就需要将BOOK的成员重新书写一遍,当然这个了例子中成员数量并不多,如在成员数量达到20个、50个、甚至100个的时候我们再去重新书写就会很麻烦,且代码量也会大大增加。那么我们只需要在结构体BOOK2中定义一个BOOK 类型的变量,我们在创建BOOK2类型变量时也能获得和BOOK类型一样的地址空间。这就是使用结构体嵌套的意义。


注意事项

Tips


关于结构体中的字符串赋值问题:


在定义结构体类型的时候如果需要进行字符串的操作的话,可以通过创建一个字符数组空间来存放

关于strcpy函数不安全问题:

#pragma warning(disable:4996) 警告注解(禁用:4996)

关于指针常量和常量指针:

指针常量是指指针本身是个常量,不能在指向其他的地址,写法如下:

int *const n;

常量指针是指针指向的内容是常量,可以有一下两种定义方式。

const int * n;

int const * n;



版权声明:本文为songchi030602原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。