在将变量传递给函数之前,在C中声明变量更好吗



或者这没关系吗?

我正在学习C并掌握结构。我试图模仿一个基本的";构造函数";方法,方法是将字符串值传递给一个方法,创建一个新的结构对象,然后从函数中返回。我已经意识到有几种允许的方法:

  1. 直接创建一个结构对象,而无需卸载到方法
  2. 声明我的结构对象的所有成员变量,然后将其传递给"构造函数"方法
  3. 将要填充对象的值直接传递到"构造函数"方法中,并将结果存储在结构对象中
  4. 在一行中使用我的"constructor"方法创建和使用结构对象,而不存储它

这是我的代码,你会明白我的意思:

#include <stdio.h>
#include <string.h>
struct Book {
char title[50];
char author[50];
int pageCount;
};
void printBook(struct Book _book) {
printf("%s by %s is %d pages long.n", _book.title, _book.author, _book.pageCount);
}
struct Book createBook(char *title, char *author, int pageCount) {
struct Book newBook;
strcpy(newBook.title, title);
strcpy(newBook.author, author);
newBook.pageCount = pageCount;
return newBook;
}
int main() {
// 1. Create a struct object directly.
struct Book hp1;
strcpy(hp1.title, "Harry Potter and the Philosopher's Stone");
strcpy(hp1.author, "J. K. Rowling");
hp1.pageCount = 223;
printBook(hp1);

// 2. Declare the member variables, then pass to a 'constructor' method.
char t2[] = "A Game of Thrones";
char a2[] = "George R. R. Martin";
int pc2 = 687;    
struct Book got1 = createBook(t2, a2, pc2);
printBook(got1);

// 3. Directly pass the member data to the 'constructor' method.
struct Book ag = createBook("American Gods", "Neil Gaiman", 465);
printBook(ag);

// 4. Create a new object instance without storing it.
printBook(createBook("Coraline", "Neil Gaiman", 186));
return 0;
}

我的问题是,这些不同方法的优点和缺点是什么?我知道,如果你想重用对象,方法4显然是不明智的,但它适合一次性使用吗?将字符串值传递给函数而不先将其存储在变量中(方法3(是否存在任何隐藏成本,或者这总是比先存储它(方法2(更具性能?

您应该注意,如果您传递的字符串长度超过50字节,此函数将导致未定义的行为。

在这种情况下,应该使用strncpy,并确保0-byte位于数组的末尾。

struct Book createBook(char *title, char *author, int pageCount)
{
struct Book newBook;
strncpy(newBook.title, title, sizeof(title));
strncpy(newBook.author, author, sizeof(author));
newBook.title[49] = 0;   // Truncate the string if it was too long
newBook.author[49] = 0;
newBook.pageCount = pageCount;
return newBook;
}

情况1并不是真正的";构造函数";因为你只需在需要的地方初始化它。

情况2是浪费堆栈空间,因为您在堆栈上创建了一个数据副本,然后将其传递到堆栈上创建另一个副本,并将其传递回堆栈,这也将在堆栈上生成一个副本。之后,您的结构中已经有了值,所以我会引用那些不再需要的变量的insead。

案例3+4基本相同,是最好的方法。如果您不再需要本地对象,只是为了调用方法,那么就不需要保留副本。

不过,您应该意识到,尤其是对于较大的结构,按值复制对象是非常无效的,因此您可能必须考虑动态分配对象,并在完成后释放它。由于C不像C++那样提供析构函数机制,所以您必须自己做。

您实现";构造函数";不过不需要任何解除分配。

相关内容

最新更新