今天看到一个有关C语言结构体的笔记,感觉很不错,拿来回一下以前的结构体知识,
C语言中,数组允许定义可存储相同类型数据项的变量(例如int i,float a等),是属于单一类型的,结构体是C语言中另一种用户可以自定义(我的理解为按照用户的想法可以随意由基本类型组成的)的可用的数据类型,它允许用户在存储不同类型的数据项。
1、使用结构体来表示一条记录,假设你想要跟踪图书馆中书本的动态,你可以需要跟踪每本书的多个属性,例如下面的属性,
Title ----> 目录
Author ----> 作者
Subject ----> 对象
BookID ----> 书本ID
下面我们来定义一个结构体,首先你必须使用的是结构体的关键字struct,使用struct定义一个包含多个成员的新数据类型,struct语句的格式如下:
struct [structure tag]
{
member definition;
member definition;
.............
member definition;
}[one or more structure variables];
其中的structure tag 是可以选择的,每个member definition是标准的变量定义,比如int i;或者float f;
或者其他有效的变量定义。在结构定义的末尾,最后一个分号之前,你可以制定一个或者多个结构体变量,这个是可选的。下面是声明Book结构体的方式:
struct Books
{
char title[50];
char author[50;
char subject[100];
int book_id;
}book;
2、访问结构体成语
为了可以访问到结构体的成员,我们使用结构体成员访问运算符(.)。成员访问运算符是结构体变量名称和我们要访问的结构体成员之间的一个句号。可以使用struct关键字来定义结构体类型的变量,下面的实例演示了结构体的用法,
编辑环境是Win7+啊哈C编辑软件
#include <stdio.h>
#include <stdlib.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 Programing");
strcpy(Book1.author,"Nuha ali");
strcpy(Book1.subject,"C Programing 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);
system("pause");
return 0;
}
你可以把结构体作为函数参数,传参方式与其他类型的变量或者指针类型。你可以使用上面实例中的方式来访问结构体变量
#include <stdio.h>
#include <stdlib.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 Programing");
strcpy(Book1.author,"Nuha ali");
strcpy(Book1.subject,"C Programing 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);
printbook(Book1);
/******输出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);
printbook(Book2);
system("pause");
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);
}
3、指向结构体的指针
可以定义指向结构的指针,方式与定义指向其他类型变量的指针相似,如下所示,
现在,可以在上述定义的指针变量中存储结构变量的地址。为了查找结构变量的地址,请把&运算符放在结构名称的前面,如下,
如下,为了使用指向该结构体的指针访问结构成员,你必须使用->运算符
#include <stdio.h>
#include <stdlib.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 Programing");
strcpy(Book1.author,"Nuha ali");
strcpy(Book1.subject,"C Programing 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);
printbook(&Book1);
/******输出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);
printbook(&Book2);
system("pause");
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);
}
4、在结构体中,还有一个概念很重要,这也是上次面试一个考官出过的题目,就是考察位域的概念
有些信息在存储的时候,并不需要占用一个完整的字节,而只需占用几个或者一个二进制位。例如在存放一个开关量时,只有0和1两种状态,用1位二进制位即可,为了节省存储空间,并使处理简便,C语言又提供一种数据结构称之为位域或者位段,
所谓的位段就是把一个字节中的二进制位划分为不同的区域,并说明每个区域的位数,每个域有一个域名,允许程序中按域名进行操作,这样就可以把几个不同的对象用一个字节的二进制位域来表示。
典型的实例:
用1位二进制存储一个开关量时,只有0和1两种状态
读取外部文件格式--可以读取非标准的文件格式,例如;9位的整数
位域定义与结构定义相仿,其形式为:
struct 位域结构名
{
位域列表;
};
其中位域列表的形式为:
例如:
struct bs
{
int a:8;
int b:2;
int c:6;
}data;
说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位
struct bs{
unsigned a :4;
unsigned :4;
unsigned b:4;
unsigned c:
}
这个位域定义中,a 占第一个字节的4位,后4位填0不使用,b从第二字节开始,占用4位,c占用4位,
由于位区域不允许跨两个字节,因此位区域的长度不能大于一个字节的长度,也就是说,不能超过8位二进制,如果最大长度大于计算机整数字长,一些编译器可能会允许区域的内存重叠,另外一些编译器可能会把大衣一个区域的部分存储在下一个字中,
位区域可以是无名位区域,这时候它只能用来作填充或者调整位置。无名的位区域是不能使用的。例如
struct k
{
int a:1;
int :2;/*该2位不能使用*/
int b:3;
int c:2;
};
从以上的分析可以看出,位区域在本质上就是一种结构体类型,不过其成员是按二进制位分配的,