C/C++结构体

1、定义结构体

结构体像子函数一样,在int mian()外定义

①定义结构

struct Mp3Song(结构体名称)
{
	char singer[32]; // 歌手名字
	char title[128]; // 歌名
	int hits; // 下载量 
}

这里的字符串数组用的是char ,但是输出用的%s,这一点怎么理解?

定义结构体不能进行初始化赋值操作,下面这种情况是错误的:

struct ABC
{
     int  a = 10;
    int  b = 11;
};

②结构体中元素的赋值

结构体中字符串赋值(数组保存字符串)

Object obj;
strcpy(obj.name,"xiaoshun");

用指针字符串时

需要注意对象复制的问题

Object obj1=obj;

浅拷贝存在的问题:当obj所指向的内存被free,则obj1无法使用了,obj1应该拥有一块自己的内存,深拷贝的方式如下:

void Copy(char* dst,char* scr)
{
    dst->name=(char*)malloc(strlen(scr->name)+1);
    strcpy(dst->name,scr->name);
    dst->id=src->id;
}

 

③main中结构体的调用

int main()
{
	struct Mp3Song mp3;

	strcpy_s(mp3.title, 128, "起风了");
	strcpy_s(mp3.singer, 32, "大神慧");	
	mp3.hits = 1293940;

	printf("歌手: %s \n", mp3.singer);
	printf("歌名: %s \n", mp3.title);
	printf("点击量: %d \n", mp3.hits);

	return 0;
}

结构体的重命名,main中重命名任然需要加上关键字struct

使用strcpy函数进行重新赋值,主要是下面两种情况:

字符串赋值:第一个参数为结构体中的元素(重命名名称.元素名称),第二个参数为定义数组的长度(长度根据情况去适当值即可,没有一个固定的标准),第三个参数为赋值的内容,printf中使用的%s,直接用重命名结构体名.元素名的方式取出具体值

整数赋值:重命名名称.元素名称=赋值内容,printf中使用的%d

 

2、结构体的使用

①main中可以定义多个重命名结构体,只需要结构体不重复即可

#include <stdio.h>
#include <string.h>

struct Color
{
	int red;
	int green;
	int blue;
};

int main()
{
	struct Color r;
	r.red = 255;
	r.green = 0;
	r.blue = 0;

	struct Color white;
	white.red = 255;
	white.green = 255;
	white.blue = 255;

	getchar();
	return 0;
}

②结构体中调用结构体

用于两种不同类型的元素能很好的划分开

#include <stdio.h>
#include <string.h>

struct Color
{
	int red;
	int green;
	int blue;
};

struct Window
{
	int x;
	int y;
	int width;
	int height;
	char title[100];

	struct Color bg_color; // 背景色
};

int main()
{
	struct Window w;
	strcpy_s(w.title, 100, "控制台");
	w.x = 50;
	w.y = 50;
	w.width = 800;
	w.height = 600;

      // 设置背景色
	w.bg_color.red = 255;
	w.bg_color.green = 255;
	w.bg_color.blue = 255;

	return 0;
}

定义时直接在一个结构体中调用另一个结构体

调用时,通过两个 . 来取出元素

③结构体赋给结构体

#include <stdio.h>
#include <string.h>

struct Point
{
	int x;
	int y;
};

int main()
{
	struct Point pt1;
	pt1.x = 8;
	pt1.y = 12;

	struct Point pt2 = pt1;
	printf("%d, %d \n", pt2.x, pt2.y);

	getchar();
	return 0;
}

 struct Point pt2 = pt1; 则 pt2 的各个字段的值与 pt1 的值相同

 

④结构体中调用结构体

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>

struct Point
{
	int x;
	int y;
};

struct Line
{
	struct Point start;
	struct Point end;
};

double line_length(struct Line* line)
{
	int dx = line->start.x - line->end.x;
	int dy = line->start.y - line->end.y;
	return sqrt((double)dx*dx + dy * dy); // sqrt求平方根
}

int main()
{
	struct Line line;
	// 起点 (0, 10)
	line.start.x = 0;
	line.start.y = 10;
	// 终点 (10, 0)
	line.end.x = 10;
	line.end.y = 0;

	// 长度
	double len = line_length(&line);
	printf("线长: %.2lf \n", len);

	getchar();
	return 0;
}

结构体中调用结构体:这里Point和start可以看作是等价的,在去结构体中的坐标时直接用:

line->start.x ,不需要line->Point->start.x

 

3、结构体指针(用箭头)

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

struct Student
{
	char name[100];   // 姓名
	bool sex; // 性别(true,男, false, 女)
	int score; // 考试成绩 (0-100)
};

int main()
{
	struct Student s;
	struct Student* ps = &s;

	strcpy_s(ps->name,100, "shao fa");
	ps->sex = true;
	ps->score = 97;

	return 0;
}

结构体中的字符元素的赋值必须要函数strcoy_s实现 

输出bool类型:本质上是一种整数类型,输出直接用%d。

 

 

4、结构体中的传值和传地址

主要观察:传入的是一个对象的值还是对象的地址


struct Object
{
	int id;
	char name[256];
};

void Test1(Object a)
{
	printf("id:%d,name:%s",a.id,a.name);
}

void Test2(Object* p)
{
	printf("id:%d,name:%s", p->id, p->name);
}

int main()
{
	Object obj = {123,"shaofa"};
	Test1(obj);
	Test2(&obj);
	return 0;
}

传值:Test1被调用时,有两个Object对象,一个是重名的结构体obj,另一个是Test1的形参a,在传值调用时,将obj的值赋值给了形参a

Object a=obj

Test2被调用时,传入对象obj的地址,用Object*指针表示对象obj的地址

Object* p=&obj

 

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

struct Student
{
	int id;  // 学号
	char name[32]; // 姓名
	bool sex; // 性别
};

void st_set(struct Student* st, int id, char* name, bool sex)
{
	st->id = id;
	strcpy_s(st->name, 32, name);
	st->sex = sex;
}

int main()
{
	struct Student stu;

	// 设置stu的各个字段
	st_set(&stu, 20180001, "shaofa", true);

	getchar();
	return 0;
}

mian中调用子函数时,传入地址用&

子函数的形参用*,任意命名,取结构体中的元素时用箭头

 

①通过传地址实现值的交换

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

void swap(int* p1, int* p2)
{
	int t = *p1;
	*p1 = *p2;
	*p2 = t;
}

int main()
{
	int a = 10;
	int b = 12;
	swap(&a, &b);

	printf("a=%d, b=%d\n", a, b);

	getchar();
	return 0;
}

 

②通过传地址实现交通灯(结构体中元素的切换)

实现颜色的显示:不知道对light->color怎么赋值?还是对题目不是很理解,这题已经给出了color的三个值,所以直接用if条件判断是否为0,1,2

实现颜色的切换:从结构体中取值,然后加1实现

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

struct TrafficLight
{
	int color; // 0, 表示红色, 1 表示黄 , 2表示绿
};

// 切到下一颜色
void change(struct TrafficLight* light)
{
	printf("切换 ...\n");
	light->color += 1;
	if (light->color >= 3)
	{
		light->color = 0;
	}
}

// 显示当前颜色
void show(struct TrafficLight* light)
{
	printf("当前颜色:");
	if (light->color == 0)
	{
		printf("红色\n");
	}
	else if (light->color == 1)
	{
		printf("黄色\n");
	}
	else if (light->color == 2)
	{
		printf("绿色\n");
	}
}

int main()
{
	struct TrafficLight tl;
	tl.color = 0; // 初始为红色

	change(&tl); // 切换到下一颜色
	show(&tl);   // 显示

	change(&tl); // 切换到下一颜色
	show(&tl);   // 显示

	getchar();
	return 0;
}

③当子函数需要返回值是直接用return

int rect_area(struct Rectangle* r)
{
	return r->width * r->height;
};

直接返回条件判断的值

bool is_right(struct Triangle* tr)
{
	int aa = tr->a * tr->a;
	int bb = tr->b * tr->b;
	int cc = tr->c * tr->c;
	return aa + bb == cc || aa + cc == bb || bb + cc == aa;
}

自己:用if条件判断,然后返回true和falese,这两句可以合并为上面一句return语句

main中写成如下:

	if (is_right(&tr))
	{
		printf("是直角三角形!\n");
	}
	else
	{
		printf("不是!\n");
	}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值