如果这是一个“基本”问题,请道歉,但我是C的新手,无法找到答案。我的问题是需要malloc
变量并在函数中返回其指针,与在函数中创建变量和return
结果相比。
首先想到的是,一旦函数终止,在函数范围内声明的任何变量都将被销毁;那么为什么以下是有效的:
int add(int a, int b)
{
int result;
result = a + b;
return result;
}
但以下不是?
char *concat(char* a, char* b)
{
char result[10];
strcat(result, a);
strcat(result, b);
return result;
}
你得到的警告是你正在向一个局部变量返回一个地址,但这也是我们在第一个函数中所做的事情?行为是否因类型而异?
对于一个更实际的例子,我对于我应该使用以下哪两个函数感到困惑,因为它们对我的程序都非常有效:
struct Card *card_create(enum Rank rank, enum Suit suit)
{
struct Card *card = malloc(sizeof(struct Card));
if(card == NULL) {
fprintf(stderr, "malloc: %s", strerror(errno));
return NULL;
}
card->rank = rank;
card->suit = suit;
return card;
}
或者:
struct Card card_create(enum Rank rank, enum Suit suit)
{
struct Card card;
card.rank = rank;
card.suit = suit;
return card;
}
再次,对不起,如果这是一个不起眼的问题,但我真的很感激解释。谢谢!
答案 0 :(得分:6)
在add()
函数中,返回其局部变量result
中保留的值(直到函数退出)。函数返回后,变量的存储空间不再可用,但存储的值只是一个数字,而不依赖于该存储。
在concat()
函数中,表达式result
将指针计算为本地存储的10 char
数组。您仍然可以返回指针的值,但是一旦该函数退出,该值的含义就不再被定义。
所以,不,返回值的行为在这些情况之间本身并不相同,但有用性 - 实际上与此相关的风险差别很大。
答案 1 :(得分:4)
行为会根据类型而有所不同吗?
有点儿。当您在C中返回某些内容时,将返回该值,而不是指向该值的指针或依赖于仍存在的任何变量的任何内容。但是,有一个不相关的规则表明,在几乎所有的上下文中,数组类型的值被隐式转换为指向数组的第一个元素的指针。因此,第二个代码片段将指针返回到数组中,而第一个片段只返回一个int。
答案 2 :(得分:1)
在第一个代码片段中,返回int变量的值。很好。
在第二个代码片段中,返回本地(堆栈)变量的地址。不行。
而且,也许是这句话:
char[10] result;
会更好:
char result[10];
如果第二个例子声明结果如下:
char result;
然后可以返回结果中的值:
return(result);
但是,第二个示例将结果定义为char数组;使结果成为指向此数组开头的指针。因此,第二个示例中结果的真值是本地堆栈内存的地址(当函数作用域终止时消失)。
第一个示例捕获结果的值(整数值)并将值发送回调用者,(不是函数本地范围中值的地址)。
答案 3 :(得分:0)
非常有趣的问题
当函数将局部变量作为vlue返回时,将创建一个新变量并将其存储在CPU寄存器中(取决于编译器)。之后,将释放局部变量。
int add(int a, int b)
{
int result;
result = a + b;
return result; // 1. A new int variable will be created and stored in CPU registers (depends on Compiler)
// 2. result will be freed at the end of function
}
在CPP中,过程与C非常相似,卡构造函数将被调用两次
struct Card card_create(enum Rank rank, enum Suit suit)
{
struct Card card;
card.rank = rank;
card.suit = suit;
return card; // 1. New Card object will be created and stored in CPU register(Depends on compiler)
// 2. card will be freed at the end of function
}
希望得到这个帮助。