关于为已定义过的结构体增加成员的问题

白菜菜和向肉肉 2019-01-22 12:19:44
①有这样的疑问,搜到了这个很久以前的帖子,也有了一些想法,但到写出来的时候却遇到了一些困难。

引用:
引用
如何用c语言给定义过的结构体增加成员-CSDN论坛
https://bbs.csdn.net/topics/391919687


②我想用版主大人的第二种方法,

引用:
引用
2.另外添加指针(如void *, 根据需要动态产生attr的结构)

struct student{
char name[20];
int age;
char sex;
int weight;
void *attr;
};


③以下是我的代码,我想为item结构体变量增加五个结构体Property类型的成员,并以后可以对这六个成员进行各自的修改之类的操作,

typedef struct tagProperty
{
char Name[64];
char Data[64];
}Property;

typedef struct tagItem
{
Property property1;
void *arr[19]; //最多可以添加19个新成员,合起来一共20个
}Item;

int main()
{
Item item;

item.arr = (Property *)("白菜2号", "是个大笨蛋!");
item.arr = (Property *)("白菜3号", "是个大笨蛋!");
item.arr = (Property *)("白菜4号", "是个大笨蛋!");
item.arr = (Property *)("白菜5号", "是个大笨蛋!");
item.arr = (Property *)("白菜6号", "是个大笨蛋!");

return 0;
}


④想了一夜,没啥头绪呢,因为试了一下发现return 0前加puts(item.arr)的话只能输出"是个大笨蛋!"。而且我这样没有办法在后面二次编辑了呢(´இ皿இ`),

⑤这...,麻烦大家了!
...全文
626 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 8 楼 赵4老师 的回复:
语法糖越甜,编译调试查错越苦!
把有限的生命浪费在品尝/品鉴无穷多种的语法糖中,我认为不值当。


哎!,这么说也有道理,一定会花好久的时间去吃苦的,不过好在是解决了也给自己以后多了一点经验。谢谢你~


void Itemcpy(Item *ItemTo, Item *ItemSource)
{
int i = 0;

for (i = 1; i <= 20; i++)
{
if ((*ItemSource).arr[i - 1] != NULL)
{
(*ItemTo).arr[i - 1] = (void *)malloc(sizeof(Property));
strcpy(((Property *)((*ItemTo).arr[i - 1]))->Data, ((Property *)((*ItemSource).arr[i - 1]))->Data);
strcpy(((Property *)((*ItemTo).arr[i - 1]))->Name, ((Property *)((*ItemSource).arr[i - 1]))->Name);
strcpy(((Property *)((*ItemTo).arr[i - 1]))->Type, ((Property *)((*ItemSource).arr[i - 1]))->Type);
}
}
}
赵4老师 2019-01-23
  • 打赏
  • 举报
回复
语法糖越甜,编译调试查错越苦! 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中,我认为不值当。
  • 打赏
  • 举报
回复
引用 4 楼 赵4老师 的回复:
#pragma warning(disable:4996) //开头加这句或项目、属性、配置属性、C/C++、预处理器、预处理器定义中添加“_CRT_SECURE_NO_WARNINGS”
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
typedef struct tagProperty
{
char Name[64];
char Data[64];
}Property;

typedef struct tagItem
{
Property property1;
void *arr[19]; //最多可以添加19个新成员,合起来一共20个
}Item;

int main()
{
Item item;
int i;
for (i=0;i<19;i++) item.arr[i]=NULL;

strcpy(item.property1.Name,"白菜1号");
strcpy(item.property1.Data,"是个大笨蛋!");
item.arr[0]=(void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[0]))->Name,"白菜2号");
strcpy(((Property *)(item.arr[0]))->Data,"是个大笨蛋!");
item.arr[1]=(void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[1]))->Name,"白菜3号");
strcpy(((Property *)(item.arr[1]))->Data,"是个大笨蛋!");
item.arr[2]=(void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[2]))->Name,"白菜4号");
strcpy(((Property *)(item.arr[2]))->Data,"是个大笨蛋!");

for (i=0;i<20;i++) {
if (i==0) {
printf("%d,%s,%s\n",i,item.property1.Name,item.property1.Data);
} else {
if (NULL!=item.arr[i-1]) {
printf("%d,%s,%s\n",i,((Property *)(item.arr[i-1]))->Name,((Property *)(item.arr[i-1]))->Data);
}
}
}

for (i=0;i<19;i++) {
if (NULL!=item.arr[i]) {
free(item.arr[i]);item.arr[i]=NULL;
}
}
return 0;
}
//0,白菜1号,是个大笨蛋!
//1,白菜2号,是个大笨蛋!
//2,白菜3号,是个大笨蛋!
//3,白菜4号,是个大笨蛋!
//


①那个...,不好意思打扰了,你的方法特别好,但我在用的时候有一个不太懂的地方,就是如果再开一个Item类型的变量temp_item,再对进行temp_item=item;把item的数据复制到temp_item里。再对temp_item进行操作却连原本item里的数据也会一同变动。

②我觉得是“temp_item=item;”这个赋值的时候、temp_item 只是把item的arr[0]、arr[1]、arr[2]所指向(Property *)型数据的地址赋给 temp_item了,

③但我不知道是不是这个样子的、也不知道该怎么避免这个问题,泣~

④以下是我的代码和运行截图~,如果有时间可以帮我简单看下~就算只是说一下思路也行(´இ皿இ`)


#pragma warning(disable:4996) //开头加这句或项目、属性、配置属性、C/C++、预处理器、预处理器定义中添加“_CRT_SECURE_NO_WARNINGS”
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

typedef struct tagProperty
{
char Name[64];
char Data[64];
}Property;

typedef struct tagItem
{
Property property1;
void *arr[19]; //最多可以添加19个新成员,合起来一共20个
}Item;

int main()
{
Item item;
int i;
for (i = 0; i < 19; i++) item.arr[i] = NULL;

strcpy(item.property1.Name, "白菜1号");
strcpy(item.property1.Data, "是个大笨蛋!");
item.arr[0] = (void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[0]))->Name, "白菜2号");
strcpy(((Property *)(item.arr[0]))->Data, "是个大笨蛋!");
item.arr[1] = (void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[1]))->Name, "白菜3号");
strcpy(((Property *)(item.arr[1]))->Data, "是个大笨蛋!");
item.arr[2] = (void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[2]))->Name, "白菜4号");
strcpy(((Property *)(item.arr[2]))->Data, "是个大笨蛋!");

for (i = 0; i < 20; i++) {
if (i == 0) {
printf("%d,%s,%s\n", i, item.property1.Name, item.property1.Data);
}
else {
if (NULL != item.arr[i - 1]) {
printf("%d,%s,%s\n", i, ((Property *)(item.arr[i - 1]))->Name, ((Property *)(item.arr[i - 1]))->Data);
}
}
}

Item temp_item;
temp_item = item;

strcpy(temp_item.property1.Name, "白菜999号");
strcpy(((Property *)(temp_item.arr[0]))->Name, "白菜888号");

for (i = 0; i < 20; i++) {
if (i == 0) {
printf("%d,%s,%s\n", i, item.property1.Name, item.property1.Data);
}
else {
if (NULL != item.arr[i - 1]) {
printf("%d,%s,%s\n", i, ((Property *)(item.arr[i - 1]))->Name, ((Property *)(item.arr[i - 1]))->Data);
}
}
}

for (i = 0; i < 19; i++) {
if (NULL != item.arr[i]) {
free(item.arr[i]); item.arr[i] = NULL;
}
}
return 0;
}
//0,白菜1号,是个大笨蛋!
//1,白菜2号,是个大笨蛋!
//2,白菜3号,是个大笨蛋!
//3,白菜4号,是个大笨蛋!
//0,白菜1号, 是个大笨蛋!
//1,白菜888号, 是个大笨蛋!
//2,白菜3号, 是个大笨蛋!
//3,白菜4号, 是个大笨蛋!



赵4老师 2019-01-22
  • 打赏
  • 举报
回复
#pragma warning(disable:4996) //开头加这句或项目、属性、配置属性、C/C++、预处理器、预处理器定义中添加“_CRT_SECURE_NO_WARNINGS”
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
typedef struct tagProperty
{
char Name[64];
char Data[64];
}Property;

typedef struct tagItem
{
Property property1;
void *arr[19]; //最多可以添加19个新成员,合起来一共20个
}Item;

int main()
{
Item item;
int i;
for (i=0;i<19;i++) item.arr[i]=NULL;

strcpy(item.property1.Name,"白菜1号");
strcpy(item.property1.Data,"是个大笨蛋!");
item.arr[0]=(void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[0]))->Name,"白菜2号");
strcpy(((Property *)(item.arr[0]))->Data,"是个大笨蛋!");
item.arr[1]=(void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[1]))->Name,"白菜3号");
strcpy(((Property *)(item.arr[1]))->Data,"是个大笨蛋!");
item.arr[2]=(void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[2]))->Name,"白菜4号");
strcpy(((Property *)(item.arr[2]))->Data,"是个大笨蛋!");

for (i=0;i<20;i++) {
if (i==0) {
printf("%d,%s,%s\n",i,item.property1.Name,item.property1.Data);
} else {
if (NULL!=item.arr[i-1]) {
printf("%d,%s,%s\n",i,((Property *)(item.arr[i-1]))->Name,((Property *)(item.arr[i-1]))->Data);
}
}
}

for (i=0;i<19;i++) {
if (NULL!=item.arr[i]) {
free(item.arr[i]);item.arr[i]=NULL;
}
}
return 0;
}
//0,白菜1号,是个大笨蛋!
//1,白菜2号,是个大笨蛋!
//2,白菜3号,是个大笨蛋!
//3,白菜4号,是个大笨蛋!
//
赵4老师 2019-01-22
  • 打赏
  • 举报
回复
“变量赋值”和“变量初始化”不是一回事!
“变量赋值”发生在运行期,其写法遵循赋值语法规定。
“变量初始化”发生在编译期或运行期,其写法遵循初始化列表语法规定。
赵4老师 2019-01-22
  • 打赏
  • 举报
回复
请牢记:源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要,重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。

意思是你程序结构看上去再合理,再简洁,也不一定比看上去一团乱麻的程序结构在运行或修改时更不易出错,更方便修改,出错了更容易找到哪里出错和具体出错的原因,更容易改正错误。

试对比
图书馆(对图书的分类够结构化了吧)

搜索引擎(可看作是扁平化任何结构数据,仅支持全文检索)
哪个处理信息更方便、更高效。

所以
与其费劲去重构代码让其看上去更简洁、更合理
不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。

结构越复杂,越难修改,越难除错。
有时(甚至大多数时候),看上去越合理、越简洁的代码,运行起来性能越差,出错时查找原因越难,找到出错原因后改正越费劲。

程序员要做的不是尽力避免错误,而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误,“快速的失败”远胜过“预防错误”。Fred George

前微软C#编辑器的开发主管Jay Bazuzi列出的一些有助于找到正确方向的问题;他觉得前同事们应该用这些问题来问自己;实际上不管在哪里工作的开发者们都应该经常问问自己这些问题:
◆“要保证这个问题不会再出现,我该怎么做?”
◆“要想少出些Bug,我该怎么做?”
◆“要保证Bug容易被修复,我该怎么做?”
◆“要保持对变化的快速响应,我该怎么做?”
◆“要保证我的软件的运行速度,我该怎么做?”
如果大多数团队都能不时问一下自己,必定会从中得益,因为这些都是真正强而有力的问题。
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
万分感谢!(五笔不小心)
  • 打赏
  • 举报
回复
引用 4 楼 赵4老师 的回复:
#pragma warning(disable:4996) //开头加这句或项目、属性、配置属性、C/C++、预处理器、预处理器定义中添加“_CRT_SECURE_NO_WARNINGS”
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
typedef struct tagProperty
{
char Name[64];
char Data[64];
}Property;

typedef struct tagItem
{
Property property1;
void *arr[19]; //最多可以添加19个新成员,合起来一共20个
}Item;

int main()
{
Item item;
int i;
for (i=0;i<19;i++) item.arr[i]=NULL;

strcpy(item.property1.Name,"白菜1号");
strcpy(item.property1.Data,"是个大笨蛋!");
item.arr[0]=(void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[0]))->Name,"白菜2号");
strcpy(((Property *)(item.arr[0]))->Data,"是个大笨蛋!");
item.arr[1]=(void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[1]))->Name,"白菜3号");
strcpy(((Property *)(item.arr[1]))->Data,"是个大笨蛋!");
item.arr[2]=(void *)malloc(sizeof(Property));
strcpy(((Property *)(item.arr[2]))->Name,"白菜4号");
strcpy(((Property *)(item.arr[2]))->Data,"是个大笨蛋!");

for (i=0;i<20;i++) {
if (i==0) {
printf("%d,%s,%s\n",i,item.property1.Name,item.property1.Data);
} else {
if (NULL!=item.arr[i-1]) {
printf("%d,%s,%s\n",i,((Property *)(item.arr[i-1]))->Name,((Property *)(item.arr[i-1]))->Data);
}
}
}

for (i=0;i<19;i++) {
if (NULL!=item.arr[i]) {
free(item.arr[i]);item.arr[i]=NULL;
}
}
return 0;
}
//0,白菜1号,是个大笨蛋!
//1,白菜2号,是个大笨蛋!
//2,白菜3号,是个大笨蛋!
//3,白菜4号,是个大笨蛋!
//


真的很谢谢你!成分感谢!祝大佬工作顺心(*°▽°)ノ

15,440

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧