C语言学习结构
结构
一.声明结构类型
#include <stdio.h> struct date { //声明结构类型,把结构放在外面,所有函数就都能使用 int month; int day; int year; }; int main(int argc, char const *argv[]) { struct date today; //定义了一个struct date 类型的变量today today.month = 9; today.day = 10; today.year = 2019; printf("Today's date is %i-%i-%i.\n",today.year,today.month,today.day); return 0; }
• 和本地变量一样,在函数内部声明的结构类型只能在函数内部使用
• 所以通常在函数外部声明结构类型,这样就可以被多个函数所使用了
二.声明结构的形式
对于第一和第三种形式,都声明了结构point。但是第二种形式没有声明point,只是定义了两个变量
三.结构变量
struct date today;
today.month=06;
today.day=19;
today.year=2005;
四.结构成员
• 结构和数组有点像
• 数组用[]运算符和下标访问其成员
• a[0] = 10;
• 结构用.运算符和名字访问其成员
• today.day
• student.firstName
• p1.x
• p1.y
五.结构运算
要访问整个结构,直接用结构变量的名字
• 对于整个结构,可以做赋值、取地址,也可以传递给函数参数
• p1 = (struct point){5, 10};
// 相当于p1.x = 5;
p1.y = 10;
• p1 = p2;
// 相当于p1.x = p2.x; p1.y = p2.y;
复合字面量
• today = (struct date) {9,25,2004};
• today = (struct date) {.month=9, .day=25,year=2004};
六.结构指针
• 和数组不同,结构变量的名字并不是结构变量的地址,必须使用&运算符
• struct date *pDate = &today;
#include <stdio.h> struct date { int month; int day; int year; }; int main(int argc, char const *argv[]) { struct date today; today = (struct date){9,10,2019}; struct date day; day =today; struct date *pDate = &today; printf("Today's date is %i-%i-%i.\n", today.year,today.month,today.day); printf("The day's date is %i-%i-%i.\n", day.year,day.month,day.day); printf("address of today is %p\n",pDate); return 0; }
七.结构与函数
1.结构作为函数
• 整个结构可以作为参数的值传入函数
• 这时候是在函数内新建一个结构变量,并复制调用者的结构的值
• 也可以返回⼀个结构
• 这与数组完全不同
2.输入结构
• 没有直接的方式可以一次scanf一个结构
• 如果我们打算写一个函数来读入结构
• ->
• 但是读入的结构如何送回来呢?
• 记住C在函数调用时是传值的
• 所以函数中的p与main中的y是不同的
• 在函数读入了p的数值之后,没有任何东西回到main,所以y还是 {0, 0}
#include <stdio.h> struct point { int x; int y; }; void getStruct(struct point); void output(struct point); void main( ) { struct point y = {0, 0}; getStruct(y); output(y); } void getStruct(struct point p) { scanf("%d", &p.x); scanf("%d", &p.y); printf("%d,%d\n", p.x, p.y); } void output(struct point p) { printf("%d, %d", p.x, p.y); }
3 解决的方案
• 之前的方案,把一个结构传入了函数,然后在函数中操作,但是没有返回回去
• 问题在于传入函数的是外面那个结构的克隆体,而不是指针
• 传入结构和传入数组是不同的
• 在这个输入函数中,完全可以创建一个临时的结构变量,然后把这个结构返回给调用者
也可以把y的地址传给函数,函数的参数类型是指向一个结构的指针。不过那样的话,访问结构的成员的方式需要做出调整。
4.结构指针作为参数
5.指向结构的指针
用->表示指针所指的结构变量中的成员
6.结构指针参数
#include <stdio.h> struct point { int x; int y; }; struct point* getStruct(struct point*); void output(struct point); void print(const struct point *p); int main(int argc,char const *argv[]) { struct point y = {0,0}; getStruct(&y); output(y); output(*getStruct(&y)); print(getStruct(&y)); } struct point* getStruct(struct point *p) { scanf("%d",&p->x); scanf("%d",&p->y); printf("%d,%d\n",p->x,p->y); return p; } void output(struct point p) { printf("%d,%d\n",p.x,p.y); } void print(const struct point *p) { printf("%d,%d",p->x,p->y); }
• 好处是传入传出只是一个指针的大小
• 如果需要保护传入的结构不被函数修改
• const struct point *p
• 返回传入的指针是一种套路
7.结构中的结构
结构数组:
struct date dates[100];
struct date dates[] = {
{4,5,2005},{2,4,2005}};
struct dateAndTime {
struct date sdate;
struct time stime;
};
嵌套的结构
8.结构中的结构的数组
#include <stdio.h> struct point{ int x; int y; }; struct rectangle { struct point p1; struct point p2; }; void printRect(struct rectangle r) { printf("<%d, %d> to <%d, %d>\n", r.p1.x, r.p1.y, r.p2.x, r.p2.y); } int main(int argc, char const *argv[]) { int i; struct rectangle rects[ ] = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}; // 2 rectangles for(i=0;i<2;i++) printRect(rects[i]); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!