鉴于您的 C# 代码,您拥有的是 readonly 自动属性。你可以像这样编写你的 C# 代码:
class ComplexNumber
{
public double real;
public double imag;
public readonly double abs;
public ComplexNumber(double real, double imag)
{
this.real = real;
this.imag = imag;
this.abs = Math.Pow(real*real + imag*imag , 0.5f);
}
}
暂时忘记这不是 C# 中最好的风格。相关的变化是,你的类现在只有 fields 而不是 properties,你可以在 C 中做一些非常相似的事情:
#include <stdio.h>
#include <math.h>
struct ComplexNumber
{
double real;
double imag;
const double abs;
};
#define ComplexNumber_init(r,i) { \
.real=(r), .imag=(i), .abs=pow((r)*(r)+(i)*(i), .5) }
int main(void)
{
struct ComplexNumber cnum = ComplexNumber_init(4.0, 2.0);
printf("%f\n", cnum.abs);
}
这里的关键组成部分是一个 struct 成员上的 const 限定符。有了这个,您可以仅在初始化时设置值,以后再也不可以了。效果与C#的readonly相当。 C# 也有const,但使用readonly,您可以在构造函数中额外设置值。
如果您想要与原始 C# 代码等效的代码,则必须注意 C# 中的 properties 始终转换为方法 -- getter 和 setter。在您的示例中,您使用的是 自动属性,这意味着,由于您没有为 getter 和 setter 指定函数体,因此会自动为您创建默认主体,只需访问私有字段.
C 中没有这样的东西,但是您可以手动创建相同的东西,下面是一个示例。
请注意,我稍微更改了语义,因为在不更新 abs 的情况下让 real 和 imag 可以更改,就像您的 C# 代码中的情况一样,这可能不是最明智的做法。
另外请注意,对于这个小例子来说,这完全是矫枉过正,我只是添加它来展示如何在 C 中编写“类”的可能性。
compnum.h:
#ifndef COMPNUM_H
#define COMPNUM_H
typedef struct ComplexNumber ComplexNumber;
// "constructor":
ComplexNumber *ComplexNumber_create(double real, double imag);
// getters and setters:
double ComplexNumber_real(const ComplexNumber *self);
void ComplexNumber_setReal(ComplexNumber *self, double real);
double ComplexNumber_imag(const ComplexNumber *self);
void ComplexNumber_setImag(ComplexNumber *self, double imag);
double ComplexNumber_abs(const ComplexNumber *self);
// "destructor":
void ComplexNumber_destroy(ComplexNumber *self);
#endif
compnum.c:
#include <math.h>
#include <stdlib.h>
#include "compnum.h"
// the struct itself is completed here and not in compnum.h -- this way, its
// members are *really* "private". They can't be seen by other translation
// units just including compnum.h.
struct ComplexNumber
{
double real;
double imag;
// don't need abs here, it's calculated
};
ComplexNumber *ComplexNumber_create(double real, double imag)
{
ComplexNumber *self = malloc(sizeof(*self));
if (!self) return 0;
self->real = real;
self->imag = imag;
return self;
}
double ComplexNumber_real(const ComplexNumber *self)
{
return self->real;
}
void CompexNumber_setReal(ComplexNumber *self, double real)
{
self->real = real;
}
double ComplexNumber_imag(const ComplexNumber *self)
{
return self->imag;
}
void ComplexNumber_setImag(ComplexNumber *self, double imag)
{
self->imag = imag;
}
double ComplexNumber_abs(const ComplexNumber *self)
{
return pow(self->real*self->real + self->imag*self->imag, .5);
}
void ComplexNumber_destroy(ComplexNumber *self)
{
free(self);
}
main.c:
#include <stdio.h>
#include "compnum.h"
int main(void)
{
ComplexNumber *cnum = ComplexNumber_create(4.0, 2.0);
printf("%f\n", ComplexNumber_abs(cnum));
ComplexNumber_destroy(cnum);
}