今天我在教几个朋友如何使用C结构体。其中一个问你是否可以从函数返回结构体,我回答说:“不能!你会返回指向动态错误结构的指针。”
来自一个主要做c++的人,我期望不能按值返回结构。在c++中,你可以重载对象的操作符=,使用函数按值返回对象是完全有意义的。然而,在C语言中,你没有这个选项,所以它让我思考编译器实际上在做什么。考虑以下几点:
struct MyObj{
double x, y;
};
struct MyObj foo(){
struct MyObj a;
a.x = 10;
a.y = 10;
return a;
}
int main () {
struct MyObj a;
a = foo(); // This DOES work
struct b = a; // This does not work
return 0;
}
我明白为什么struct b = a;不应该工作——您不能重载数据类型的operator =。为什么a = foo();编译好了吗?它的意思是不是不是struct b = a;?也许要问的问题是:结合=符号的return语句到底有什么作用?
回传结构体没有问题。它将通过值传递
但是,如果结构体包含任何具有局部变量地址的成员呢
struct emp {
int id;
char *name;
};
struct emp get() {
char *name = "John";
struct emp e1 = {100, name};
return (e1);
}
int main() {
struct emp e2 = get();
printf("%s\n", e2.name);
}
现在,这里的e1.name包含函数get()的本地内存地址。
一旦get()返回,name的本地地址将被释放。
因此,在调用者中,如果我们试图访问该地址,它可能会导致分割错误,因为我们正在尝试一个释放的地址。这很糟糕。
这里是e1。Id将完全有效,因为它的值将被复制到e2.id
因此,我们应该总是尽量避免返回函数的本地内存地址。
任何错误的东西都可以在需要的时候返回
是的,我们可以通过结构,也可以返回结构。你是对的,但你实际上没有传递数据类型,应该像这个结构MyObj b = a。
实际上,当我试图找到一个更好的解决方案,在不使用指针或全局变量的情况下为函数返回多个值时,我也知道了。
下面是同样的例子,计算出一个学生平均分数的偏差。
#include<stdio.h>
struct marks{
int maths;
int physics;
int chem;
};
struct marks deviation(struct marks student1 , struct marks student2 );
int main(){
struct marks student;
student.maths= 87;
student.chem = 67;
student.physics=96;
struct marks avg;
avg.maths= 55;
avg.chem = 45;
avg.physics=34;
//struct marks dev;
struct marks dev= deviation(student, avg );
printf("%d %d %d" ,dev.maths,dev.chem,dev.physics);
return 0;
}
struct marks deviation(struct marks student , struct marks student2 ){
struct marks dev;
dev.maths = student.maths-student2.maths;
dev.chem = student.chem-student2.chem;
dev.physics = student.physics-student2.physics;
return dev;
}