C语言学习笔记——结构体

一、结构体

1、结构体定义:结构体是将不同类型的数据按照一定的功能需求进行整体封装,封装的数据类型与大小均可以由用户指定。
2、结构体声明:声明一个结构体类型的一般形式为:

struct 结构体名
{
    成员列表
};

例如:

struct BOOK {
       char title[20];
       char author[20];
       float value;
};

注意:“结构体名”的命名规范是全部使用大写字母。
3、定义结构体变量:定义结构体类型变量有两种方法。
(1)先声明“结构体类型”,再定义“结构体类型变量”。这种方式比较自由。
比如在所有函数前定义了一个结构体类型 struct BOOK,那么就可以在所有函数中使用它来定义局部的结构体类型变量。如:

struct BOOK book1,book2;

book1和book2 就是我们定义的结构体变量名。定义了结构体变量之后,系统就会为之分配内存单元。如果 book1和book2是在某个函数中定义的局部变量,那么就只能在该函数中使用。在其他函数中可以定义重名的结构体变量而不会相互产生影响。
(2)声明结构体类型的同时定义结构体变量。
注意:如果在所有函数前声明结构体类型,那么定义的变量就是全局变量;而如果要定义局部变量,那么就只能在某个函数中对结构体类型进行声明,从而导致只能在这个函数中使用这个类型。如:

struct BOOK {
       char title[20];
       char author[20];
       float value;
}book1,book2;

这样就声明了一个结构体类型,并用这个类型定义了结构体变量 book1和book2。
注意:(1)“结构体类型”的声明和使用与函数的定义和使用有所不同,函数的定义可以放在调用处的后面,只需在前面声明一下即可。但是“结构体类型”的声明必须放在“使用结构体类型定义结构体变量”的前面。
(2)如果程序规模比较大,往往会将结构体类型的声明集中放到一个以 .h 为后缀的头文件中。哪个源文件需要用到此结构体类型,只要用 #include 命令将该头文件包含到该文件中即可,这样做便于修改和使用。
4、结构体变量引用
(1)引用方式为:结构体变量名.成员名;如:book1.value=1.95;
(2)如果结构体类型中的成员也是一个结构体类型,则要用若干个“.”,一级一级地找到最低一级的成员。
(3)可以引用“结构体变量成员”的地址,也可以引用“结构体变量”的地址。如: &book1.title& book1 ,前者表示 book1.title 这个成员在内存中的首地址,后者表示结构体变量 book1 在内存中的首地址。它们表示的是同一个内存空间的地址,但它们的类型是不同的。& book1是结构体变量的地址 ,是 struct BOOK* 型的;而 book1.title是数组名,所以是 char* 型的。类型的不同导致它们在程序中不能相互替换。
(4)“结构体变量名”可以与“ 结构体成员名”同名;“结构体变量名”可以与“结构体名”同名;两个结构体类型定义的结构体变量中的成员可以同名。
5、结构体变量的初始化:结构体变量的初始化方式有两种。
(1)定义的时候初始化,如:

struct BOOK book1={ "C Primer Plus","Prata,S.",19.5};

(2)定义之后对结构体变量进行初始化,如;

struct BOOK book1;
strcpy(book1.title, "C Primer Plus"); 
strcpy(book1.author, "Prata,S.");
book1.value=19.5;

二、结构体数组

1、结构体数组定义struct BOOK book[5];;这就定义了一个结构体数组,共有 5 个元素,每个元素都是一个结构体变量,都包含所有的结构体成员。
结构体数组的引用与引用一个结构体变量在原理上是一样的。只不过结构体数组中有多个结构体变量,可以利用 for 循 环一个一个地使用结构体数组中的元素。如:

# include <stdio.h>
# include <string.h>
struct BOOK {
       char title[20];
       char author[20];
       float value;
};
void OutputBOOK(struct BOOK book[5]); //函数声明, 该函数的功能是输出书的信息
int main(void)
{
    int i;
    struct BOOK book[5];
    for (i=0; i<5; ++i)
    {
        printf("请输入第%d本书的信息:", i+1);
        scanf ("%s%s%f", book[i].title, book[i].author, &book[i].value);
    }
    OutputBOOK(book);
    return 0;
}
void OutputBOOK(struct BOOK book[5])
{
    for (int i=0;i<5;i++){
		printf("书名:%s 作者:%s 价格:%lf \n", book[i].title, book[i].author, book[i].value);
	}
}

2、结构体数组定义时初始化:结构体数组的初始化与数值型数组的初始化是一样的,数值型数组初始化的方法和需要注意的问题在结构体数组的初始化中同样适用,因为不管是数值型数组还是结构体数组都是数组。如:

struct BOOK book[5]={ {"数学",''人教版'',26},{''英语”,''人教版'',28},{''语文'',''人教版'',32},{''物理'',''人教版'',36},{''化学'',''人教版'',28} };

三、结构体指针

1、指向结构体变量的指针

struct BOOK *p = NULL;  /*定义一个指向struct BOOK结构体类型的指针变量p*/
p = &book1;  /*p指向结构体变量book1的首地址, 即第一个成员的地址*/

用指针引用结构体变量成员的方式是:
(1)(*指针变量名).成员名,如:(*p).book1.value = 26;
(2)指针变量名->成员名,如:p->book1.value = 26;
2、指向结构体数组的指针
如果定义一个结构体指针变量并把结构体数组的数组名赋给这个指针变量的话,就意味着将结构体数组的第一个元素,即第一个结构体变量的地址,也即第一个结构变量中的第一个成员的地址赋给了这个指针变量。如:

struct BOOK book[5]={ {"数学",''人教版'',26},{''英语”,''人教版'',28},{''语文'',''人教版'',32},{''物理'',''人教版'',36},{''化学'',''人教版'',28} };
struct STU *p = book;

此时指针变量 p 就指向了结构体数组的第一个元素,即指向 book[0]。我们知道,当一个指针指向一个数组后,指针就可以通过移动的方式指向数组的其他元素。
这个原则对结构体数组和结构体指针同样适用,所以p+1 就指向 book[1] 的首地址;p+2 就指向 book[2]的首地址……所以只要利用 for 循环,指针就能一个个地指向结构体数组元素。如:

# include <stdio.h>
struct BOOK {
       char title[20];
       char author[20];
       float value;
};
int main(void)
{
    struct BOOK book[5]={ { "数学","人教版",26 },{ "英语","人教版",28 },{ "语文","人教版",32 },{ "物理","人教版",36 },{ "化学","人教版",28 } };
    struct BOOK *p = book;
    for (int i=0; i<5; i++)
    {
        printf("书名:%s 作者:%s 价格:%lf \n", p->title, p->author, p->value);
        p++;
    }
    return 0;
}

输出:
书名:数学 作者:人教版 价格:26.000000
书名:英语 作者:人教版 价格:28.000000
书名:语文 作者:人教版 价格:32.000000
书名:物理 作者:人教版 价格:36.000000
书名:化学 作者:人教版 价格:28.000000
其中,此外同前面“普通数组和指针的关系”一样,当指针变量 p 指向 book[0] 时,p[0] 就等价于 book[0];p[1] 就等价于 book[1];p[2] 就等价于 book[2]……所以 book[0].value 就可以写成 p[0].value,其他同理。下面将上面的程序用 p[i] 的方式修改一下:

for (int i=0; i<5; i++){
      printf("书名:%s 作者:%s 价格:%lf \n", p[i].title,  p[i].author,  p[i].value);
        }

四、结构体与函数

结构体可以作为函数参数使用,可以选择传递结构体本身,还是传递指向结构体的指针或者是结构体成员。
1、传递结构体成员

# include <stdio.h>
struct BOOK {
       char title[20];
       char author[20];
       float value;
};
float sum(float,int);
int main(void)
{
    struct BOOK book= { "数学","人教版",26 };
    printf("总价为:%f\n",sum(book.value,10));//传递结构体成员
    return 0;
}
float sum(float x,int y){
	return(x*y);
}

2、传递结构体地址

# include <stdio.h>
struct BOOK {
       char title[20];
       char author[20];
       float value;
};
float sum(const struct BOOK *);
int main(void)
{
    struct BOOK book= { "数学","人教版",26 };
    printf("总价为:%f\n",sum(&book));//传递结构体地址
    return 0;
}
float sum(const struct BOOK * value){
	return((value->value)*10);
}

3、传递结构

# include <stdio.h>
struct BOOK {
       char title[20];
       char author[20];
       float value;
};
float sum(const struct BOOK book);
int main(void)
{
    struct BOOK book= { "数学","人教版",26 };
    printf("总价为:%f\n",sum(book));//传递结构
    return 0;
}
float sum(const struct BOOK book){
	return((book.value)*10);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值