【发布时间】:2012-08-19 22:55:46
【问题描述】:
我会避免使用 malloc 来初始化结构,并且我正在寻找使用 oo 样式(如果可能)设计 C 软件的最佳实践。
只有 C99,不是 C++
第一个问题,当使用像对象这样的结构时,什么是可取的? typedef 它的指针与否?
这些是我的测试(所有工作都使用 gcc 编译器):
案例1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct sItem{
int n;
char* text;
} oItem, *Item;
int main(int argc, char** argv) {
Item i1=(&(oItem){.n=1, .text="A"});
Item i2=(&(oItem){.n=100, .text="ABC"});
printf("%d, %s, %d\n", i1->n, i1->text, sizeof(*i1)); // 1, "A", 8
printf("%d, %s, %d\n", i2->n, i2->text, sizeof(*i2)); // 1, "ABC", 8
return (EXIT_SUCCESS);
}
这可行,但我认为它不应该,因为文本未初始化为包含字符串。 这是一段无效的代码吗?
案例2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct sItem{
int n;
char text[5];
} oItem, *Item;
int main(int argc, char** argv) {
Item i1=(&(oItem){.n=1, .text="A"});
Item i2=(&(oItem){.n=100, .text="ABC"});
printf("%d, %s, %d\n", i1->n, i1->text, sizeof(*i1)); // 1, "A", 12
printf("%d, %s, %d\n", i2->n, i2->text, sizeof(*i2)); // 1, "ABC", 12
return (EXIT_SUCCESS);
}
这行得通,我认为它是正确的,是吗?
案例 3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Item_new(i, n, s) (&(oItem){0});Item_ctor(i, n, s);
#define Item_neww(i, x, s) (&(oItem){\
.n=x,\
.text=s\
})
typedef struct sItem{
int n;
char text[5];
} oItem, *Item;
void Item_ctor(Item i, int n, char* text){
i->n=n;
strcpy(i->text, text);
}
int main(int argc, char** argv) {
Item i1=Item_new(i1, 10, "ABC");
Item i2=Item_neww(i2, 10, "ABC");
printf("%d, %s, %d\n", i1->n, i1->text, sizeof(*i1)); // 10, "ABC", 12
printf("%d, %s, %d\n", i2->n, i2->text, sizeof(*i2)); // 10, "ABC", 12
return (EXIT_SUCCESS);
}
我觉得这很好,但是隐藏了代码,而且可能有害,你觉得呢? I case 3,什么是最佳选择:宏还是构造函数?
【问题讨论】:
-
示例 1 和 2 不是有效代码。您不能获取临时地址并期望它包含有效值。如果你想要一个堆栈分配的指针,请改用 alloca。
-
2 有效,为什么说无效?
-
因为你取的是临时值的地址,这是未定义的行为。
-
万一2我不使用临时值的地址...
-
我不会对名称不反映它是指针的指针进行类型定义。如果 Item_ptr 太长,我会使用 Item *。
标签: c oop constructor struct