S1E44:传递结构体变量和结构体指针 课后作业

测试题:
0. 如果将一个结构体变量赋值给另外一个不同类型的结构体变量,会发生什么事情?

...
        struct Test1
        {
                int x;
                int y;
        }t1;
    
        struct Test2
        {
                int x;
                int y;
                int z;
        }t2;
    
        t1.x = 3;
        t1.y = 4;
    
        t2 = t1;
...

答:传递的值会紊乱,z没有得到赋值(错误

答案:会报错。
解析:通过赋值号传递结构体变量,应该确保两个变量是相同的结构体类型。

1. 请问下面定义结构体变量的代码(t1、t2、t3)中,哪一个是错误的?

...
        struct Test
        {
                int x;
                int y;
        };

        struct Test t1 = {3.0, 4.0};
        struct Test t2 = {3};
        struct Test t3 = {3, 4, 5};
...

答:t1和t3(错误

答案:t3。
解析:一言以蔽之就是——宁缺毋滥。

2. 请问下面代码会打印什么内容?

#include <stdio.h>
    
struct Test
{
        int x;
        int y;
};
    
void setTest(struct Test test)
{
        test.x = 3;
        test.y = 4;
}
    
int main()
{
        struct Test test;
    
        setTest(test);
        printf("test.x = %d\n", test.x);
        printf("test.y = %d\n", test.y);
    
        return 0;
}

答:变量的作用域不一样,打印的随机值

答案:不知道。
解析:调用 setTest() 函数的时候,代码中是进行一个值传递的过程,所以 test.x = 3; 和 test.y = 4; 这两个赋值,其实是赋给了 setTest() 函数的实参。所以,打印出来的是内存的“随机值”。如果要正确实现需求,我们应该传入的是一个指针(代码见下一题)。l

3. 请问下面代码存在什么问题?

...
        struct Book b1, b2;
    
        b1 = (struct Book *)malloc(sizeof(struct Book));
        b2 = (struct Book *)malloc(sizeof(struct Book));
        if (b1 == NULL || b2 == NULL)
        {
                printf("内存分配失败!\n");
                exit(1);
        }
...

答:定义的b1和b2数据类型是结构体,但是malloc传递的为结构体指针

答案:定义 b1、b2 变量的时候要使用指针(struct Book *b1, *b2;),因为 malloc() 函数是在堆里面抓处一个大小为 struct Book 的内存块,所以咱们需要定义一个指针指过去。

4. 请根据代码中的注释,按要求补充 setTest() 函数的内容。

#include <stdio.h>
    
struct Test
{
        int x;
        int y;
};
    
void setTest(struct Test *test)
{
        /* 这里要求给 test.x 赋值为 3 */
        /* 这里要求给 test.y 赋值为 4 */
}
    
int main()
{
        struct Test test;
    
        /* 这里要求将 test 结构体变量传递给 setTest() 函数 */
        printf("test.x = %d\n", test.x);
        printf("test.y = %d\n", test.y);
    
        return 0;
}

答:

#include <stdio.h>

struct Test
{
	int x;
	int y;
};

void setTest(struct Test *test)
{
	(*test).x = 3;
	(*test).y = 4;
}

int main()
{
	struct Test test;
	
	setTest(&test);
	printf("test.x = %d\n",test.x);
	printf("test.y = %d\n",test.y);
	
	return 0;
}

答案:

#include <stdio.h>
    
struct Test
{
        int x;
        int y;
};
    
void setTest(struct Test *test)
{
        test->x = 3;
        test->y = 4;
}
    
int main()
{
        struct Test test;
    
        setTest(&test);
        printf("test.x = %d\n", test.x);
        printf("test.y = %d\n", test.y);
    
        return 0;
}

5. 请根据代码中的注释,按要求补充 setTest() 函数的内容。

#include <stdio.h>
#include <stdlib.h>
    
struct Test
{
        int x;
        int y;
};
    
/* setTest() 函数应该返回一个指向 Test 结构体的指针 */
{
        /* 声明一个指向 Test 结构体的指针变量 pt */
    
        pt = (struct Test *)malloc(sizeof(struct Test));
        if (pt == NULL)
        {
                printf("内存分配失败!\n");
                exit(1);
        }
    
        pt->x = x;
        pt->y = y;
    
        return pt;
}
    
int main()
{
        struct Test *pt;
    
        pt = setTest(3, 4);
        printf("pt->x = %d\n", pt->x);
        printf("pt->y = %d\n", pt->y);
    
        return 0;
}

答:

#include <stdio.h>
#include <stdlib.h>
    
struct Test
{
        int x;
        int y;
};
    
/* setTest() 函数应该返回一个指向 Test 结构体的指针 */
struct Test *setTest(int x,int y)
{
        /* 声明一个指向 Test 结构体的指针变量 pt */
    	struct Test *pt;
    
        pt = (struct Test *)malloc(sizeof(struct Test));
        if (pt == NULL)
        {
                printf("内存分配失败!\n");
                exit(1);
        }
    
        pt->x = x;
        pt->y = y;
    
        return pt;
}
    
int main()
{
        struct Test *pt;
    
        pt = setTest(3, 4);
        printf("pt->x = %d\n", pt->x);
        printf("pt->y = %d\n", pt->y);
    
        return 0;
}

答案:

#include <stdio.h>
#include <stdlib.h>
    
struct Test
{
        int x;
        int y;
};
    
struct Test *setTest(int x, int y)
{
        struct Test *pt;
    
        pt = (struct Test *)malloc(sizeof(struct Test));
        if (pt == NULL)
        {
                printf("内存分配失败!\n");
                exit(1);
        }
    
        pt->x = x;
        pt->y = y;
    
        return pt;
}
    
int main()
{
        struct Test *pt;
    
        pt = setTest(3, 4);
        printf("test.x = %d\n", pt->x);
        printf("test.y = %d\n", pt->y);
    
        return 0;
}

动动手:
0. 帮助社区大妈编写一个打疫苗的登记程序。
要求实现的功能:

  • 登记姓名、年龄、第 1、2 针疫苗的接种日期
  • 如果未接种第 1 针疫苗,提示 “请尽快接种疫苗!” 并结束本次录入
  • 如果未接种第 2 针疫苗,提示 “请尽快接种第二针疫苗!”
  • 打印录入的结果

录入数据的流程图:

%39Qt]BCG,W_*.mz;O[vJ?
测试样本数量:3
程序实现效果:

答:代码有问题(错误

#include <stdio.h>

struct Time
{	
	int year;
	int month;
	int day;
};

struct Yimiao
{
	char name[8];
	int age;
	struct Time onetime;
	struct Time twotime;
};

struct Yimiao *Input(void)
{
	int one_flag,two_flag;
	
	struct Yimiao men;
	
	printf("请问姓名是:");
	scanf("%s",men.name);
	
	printf("请问年龄是:");
	scanf("%d",&men.age); 
	
	printf("请问是否接种过疫苗(Y/N):");
	scanf("%d",&one_flag);
	
	if(one_flag == 1)
	{
		printf("请录入第一针疫苗接种的日期(yyyy-mm-dd):");
		scanf("%d-%d-%d",&(men.onetime.year),&(men.onetime.month),&(men.onetime.day)); 
		
		printf("请问是否接种第二针疫苗(Y/N)");
		scanf("%d",&two_flag);
		
		if(two_flag == 1)
		{
			printf("请录入第二针疫苗接种的日期(yyyy-mm-dd):");
			scanf("%d-%d-%d",&(men.twotime.year),&(men.twotime.month),&(men.twotime.day)); 
		}
		else{
			men.twotime.year = 0;
			printf("请尽快接种第二针疫苗\n");
		}

	}
	else{
		men.onetime.year = 0;
		printf("请尽快接种疫苗!\n"); 	
	}
	printf("\n");	
	
	return (struct Yimiao *)(&men);
}


int Out(struct Yimiao *men)
{
	int i;
	printf("\n");
	printf("姓名:%s\n",men->name);
	printf("年龄:%d\n",men->age);
	if(men->onetime.year == 0)
	{
		printf("未接种疫苗\n"); 
		
	}
	else{
	printf("第一针时间:%d-%d-%d\n",men->onetime.year,men->onetime.month,men->onetime.day);	
	}
	if(men->twotime.year == 0)
	{
		printf("未接种第二针疫苗\n"); 
		
	}
	else{
		printf("第二针时间:%d-%d-%d\n",men->twotime.year,men->twotime.month,men->twotime.day);	
	}
		
	printf("\n");
}


int main()
{
	int i;
	struct Yimiao *pt[3];
	for(i=0;i<3;i++)
	{
		pt[i] = Input();
		
	}
	Out(pt[0]);
	Out(pt[1]);
	Out(pt[2]);
	
}

答:参考答案,二次作答(为什么结构体函数返回结构体类型的指针,会有问题?)

#include <stdio.h>

struct Time
{	
	int year;
	int month;
	int day;
};

struct Yimiao
{
	char name[8];
	int age;
	struct Time onetime;
	struct Time twotime;
};

struct Yimiao Input(struct Yimiao men)
{
	int one_flag,two_flag;
	
	printf("请问姓名是:");
	scanf("%s",men.name);
	
	printf("请问年龄是:");
	scanf("%d",&men.age); 
	
	printf("请问是否接种过疫苗(Y/N):");
	scanf("%d",&one_flag);
	
	if(one_flag == 1)
	{
		printf("请录入第一针疫苗接种的日期(yyyy-mm-dd):");
		scanf("%d-%d-%d",&(men.onetime.year),&(men.onetime.month),&(men.onetime.day)); 
		
		printf("请问是否接种第二针疫苗(Y/N)");
		scanf("%d",&two_flag);
		
		if(two_flag == 1)
		{
			printf("请录入第二针疫苗接种的日期(yyyy-mm-dd):");
			scanf("%d-%d-%d",&(men.twotime.year),&(men.twotime.month),&(men.twotime.day)); 
		}
		else{
			men.twotime.year = 0;
			printf("请尽快接种第二针疫苗\n");
		}

	}
	else{
		men.onetime.year = 0;
		printf("请尽快接种疫苗!\n"); 	
	}
	printf("\n");	
	
	return men;
}


int Out(struct Yimiao men)
{
	int i;
	printf("\n");
	printf("姓名:%s\n",men.name);
	printf("年龄:%d\n",men.age);
	if(men.onetime.year == 0)
	{
		printf("未接种疫苗\n"); 
		
	}
	else{
	printf("第一针时间:%d-%d-%d\n",men.onetime.year,men.onetime.month,men.onetime.day);	
	}
	if(men.twotime.year == 0)
	{
		printf("未接种第二针疫苗\n"); 
		
	}
	else{
		printf("第二针时间:%d-%d-%d\n",men.twotime.year,men.twotime.month,men.twotime.day);	
	}
		
	printf("\n");
}


int main()
{
	int i;
	struct Yimiao  pt[3];
	
	pt[0] = Input(pt[0]);
	pt[1] = Input(pt[1]);
	pt[2] = Input(pt[2]);
	
	Out(pt[0]);
	Out(pt[1]);
	Out(pt[2]);
	
}

答案:

#include <stdio.h>
    
struct Date
{
        int year;
        int month;
        int day;
};
    
struct Record
{
        char name[16];
        int age;
        struct Date first;
        struct Date second;
};
    
struct Record getInput(struct Record record)
{
        printf("请问姓名是:");
        scanf("%s", record.name);
        printf("请问年龄是:");
        scanf("%d", &record.age);
        printf("请问是否接种过疫苗(Y/N):");
    
        getchar();
        if (getchar() != 'Y')
        {
                record.first.year = 0;
                printf("请尽快接种疫苗!\n");
        }
        else
        {
                printf("请输入第一针疫苗接种的日期(yyyy-mm-dd):");
                scanf("%d-%d-%d", &record.first.year, &record.first.month, &record.first.day);

                printf("请问是否接种第二针疫苗(Y/N):");
                getchar();
                if (getchar() != 'Y')
                {
                        record.second.year = 0;
                        printf("请尽快接种第二针疫苗!\n");
                }
                else
                {
                        printf("请输入第二针疫苗接种的日期(yyyy-mm-dd):");
                        scanf("%d-%d-%d", &record.second.year, &record.second.month, &record.second.day);
                }
        }
        putchar('\n');
    
        return record;
}

void printRecord(struct Record record)
{
        printf("姓名:%s,年龄:%d\n", record.name, record.age);
    
        if (record.first.year == 0)
        {
                printf("未接种疫苗!\n\n");
        }
        else
        {
                printf("第一针疫苗接种日期:%d-%d-%d,", record.first.year, record.first.month, record.first.day);
        }
    
        if (record.first.year != 0 && record.second.year == 0)
        {
                printf("未接种第二针疫苗!\n\n");
        }
        else if(record.first.year != 0)
        {
                printf("第二针疫苗接种日期:%d-%d-%d\n\n", record.second.year, record.second.month, record.second.day);
        }
}

int main(void)
{
        struct Record r1, r2, r3;
    
        r1 = getInput(r1);
        r2 = getInput(r2);
        r3 = getInput(r3);
    
        printRecord(r1);
        printRecord(r2);
        printRecord(r3);
    
        return 0;
}

答:程序为了效率,一般不给函数传递结构体的变量,可以用指针代替
       形参用指针代替时,就没必要有函数返回值 ,此版回答为优化答案

#include <stdio.h>
 
struct Time
{    
    int year;
    int month;
    int day;
};
 
struct Yimiao
{
    char name[16];
    int age;
    struct Time onetime;
    struct Time twotime;
};


//程序为了效率,一般不给函数传递结构体的变量,可以用指针代替
//形参用指针代替时,就没必要有函数返回值 
void Input(struct Yimiao *men)
{
    int one_flag,two_flag;
    
    printf("请问姓名是:");
    scanf("%s",men->name);
    
    printf("请问年龄是:");
    scanf("%d",&(men->age)); 
    
    printf("请问是否接种过疫苗(Y/N):");
    scanf("%d",&one_flag);
    
    if(one_flag == 1)
    {
        printf("请录入第一针疫苗接种的日期(yyyy-mm-dd):");
        scanf("%d-%d-%d",&men->onetime.year,&men->onetime.month,&men->onetime.day); 
        
        printf("请问是否接种第二针疫苗(Y/N)");
        scanf("%d",&two_flag);
        
        if(two_flag == 1)
        {
            printf("请录入第二针疫苗接种的日期(yyyy-mm-dd):");
            scanf("%d-%d-%d",&men->twotime.year,&men->twotime.month,&men->twotime.day); 
        }
        else{
            men->twotime.year = 0;
            printf("请尽快接种第二针疫苗\n");
        }
    }
    else{
        men->onetime.year = 0;
        printf("请尽快接种疫苗!\n");     
    }
    printf("\n");    
    
    return men;
}
 
 
void Out(struct Yimiao *men)
{
    printf("\n");
    printf("姓名:%s\n",men->name);
    printf("年龄:%d\n",men->age);
    if(men->onetime.year == 0)
    {
        printf("未接种疫苗\n"); 
    }
    else{
    printf("第一针时间:%d-%d-%d\n",men->onetime.year,men->onetime.month,men->onetime.day);    
    }
    if(men->twotime.year == 0)
    {
        printf("未接种第二针疫苗\n");     
    }
    else{
        printf("第二针时间:%d-%d-%d\n",men->twotime.year,men->twotime.month,men->twotime.day);    
    }
        
    printf("\n");
}
 
 
int main()
{
#if 0  //这个也可以 
    struct Yimiao p1,p2,p3;
    
    Input(&p1);
    Input(&p2);
    Input(&p3);    
    
    Out(&p1);
    Out(&p2);
    Out(&p3);
#endif
    
    struct Yimiao p[3];
    Input(&p[0]);
    Input(&p[1]);
    Input(&p[2]);    
    
    Out(&p[0]);
    Out(&p[1]);
    Out(&p[2]);
    
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值