2010-09-24 118 views
1

我正在为C编写一个Unicode库作为个人练习。如果没有实际的代码,我有这样的:自动传递参数在C参考

typedef struct string { 
    unsigned long length; 
    unsigned *data; 
} string; 

// really simple stuff 

string *upush(string *s, unsigned c) { ... } 

// UTF-8 conversion 

string *ctou(char *old) { ... } 

char *utoc(string *old) { ... } 

upush推动全Unicode代码点c到的s末,根据需要重新分配。

我可以使用类这样的,例如:

string a; 
upush(&a, 0x44); 
puts(utoc(&a)); 

而不必使用&到参考传递给函数的,有一种方法可以写出这样我可以拨打:

string a; 
upush(a, 0x44); 
puts(utoc(a)); 

或者,你认为这只是最好的typedef stringstruct string指针,而不是结构本身,始终与struct string指针处理?

解决方法?由于Dummy00001,这是我现在的图书馆的一般轮廓:

typedef struct string { 
    unsigned long length; 
    unsigned *data; 
} string; 

// really simple stuff 

string *upush(string *s, unsigned c) { ... } 

// UTF-8 conversions 

string ctou(char *old) { ... } 

char *utoc(string old) { ... } 

下面是一些例子:++

string a = ctou("Hello, world"); 
upush(&a, '!'); 
puts(utoc(a)); 

我也学习,感谢Doches,在C(这是我会写这个库中的包装),你可以写原型这样做隐含传递按引用:

string *upush(string &s, unsigned c); 

对于那些有兴趣谁,这是我不断取得的进展:http://delan.ath.cx/ulib

+0

好运气的运动,unicode是非常困难的得到正确。 – 2010-09-24 09:46:25

+0

助手宏怎么样? #define upush(a,b)upush(&a,b) – Nyan 2010-09-24 10:04:52

+0

呃,这似乎有点'hackish'。 – 2010-09-24 10:11:13

回答

3

而不必使用&到参考传递给函数的,有一种方法可以写出这样我可以拨打:
字符串;
upush(a,0x44);
puts(utoc(a));

我个人比较喜欢&符号并使用它(即使在C++)这可能修改它的参数和功能访问所述结构作为一个const的情况下的功能的情况下之间进行区分。 IOW:

string a; 
upush(&a, 0x44); // pass pointer, we modify the "a" 
puts(utoc(a)); // pass "a" as a copy, utoc() doesn't modify it 

在代码上方的一个立即看到该upush()需要&a和因此潜在修改它。而utoc()采取a并且不修改它。

但最终决定如何使界面在很大程度上取决于你如何管理内存。

或者,你认为将字符串作为结构字符串指针,而不是结构本身,并且总是处理结构字符串指针会更好吗?

使符号string成为指向不透明结构的指针,仅在库本身内定义。在公共接口头:

struct string_s; 
typedef struct string_s *string; 

在内部报头:

struct string_s { 
    unsigned long length; 
    unsigned *data; 
}; 

接口功能将仅接受string这是指针。提供函数来创建新字符串(calloc(1,sizeof(string *)))并销毁它(free())。通过这种方式,您可以为应用程序提供一致的接口(开发人员不必考虑什么是指针),并且对库内部更改也是有弹性的(因为结构的结构只在库本身内部知道)。

缺点是需要使用动态内存管理来分配puny结构:malloc()/free()速度很快,但它仍然像一次矫枉过正。

+0

通过使用可变大小的结构体语法,可以避免使库执行的堆分配数加倍。但是,只要其大小发生变化,这会改变'string'结构的位置。像'upush()'这样的函数要么必须返回新的字符串,要么使用额外的间接级别(例如'upush(string ** s,unsigned c)')。 – bk1e 2010-09-24 14:56:50

1

string a在当前范围内分配你需要的内存,string *a只是一个指向内存的指针,你必须自己去malloc和free。

所以答案:取决于。如果您使用指针策略,则应该提供创建函数和销毁函数,并记住用户“忘记”使用这些函数。

+0

我想最好是坚持最初的范式。我将如何编写隐式通过引用?没有这个,我必须用'&'在字符串参数上进行所有的调用,而且看起来很笨重。 – 2010-09-24 09:46:25

+0

但是这是在C中执行此操作的正常方法。 – 2010-09-24 15:13:56

2

不幸的是,你给出的例子是在C中做引用传递的正确方法。我认为你所追求的是用于指定参数应该通过引用而不是值传递的&表示法,是一个C++ - ism(Longer, better example from IBM)。

在C++(不是C!),你可以这样写:

typedef struct _foo_t { 
    int value; 
} foo; 

void modify_foo(foo &f) 
{ 
    f.value = -1; 
} 

和你要问什么,如:

foo aFoo; 
aFoo.value = 1; 
modify_foo(aFoo); 
printf("%d\n",aFoo.value);