繁体   English   中英

就像在C#类构造函数中一样,在C结构中设置变量

[英]Setting Variables in a C struct just like in a C# class constructor

在C#的类内部,我们可以在类型的构造函数中设置变量,例如:

class ComplexNumber
{
 public double real {get; set;}
 public double imag {get; set;}
 public double abs {get;}
 public Complex Number(double real, double imag)
 {
  this.real = real;
  this.imag = imag;
  this.abs = Math.Pow(real*real + imag*imag , 0.5f);
 }
}

(如果C#代码错误,我很抱歉,我有一段时间没有写C#了,我只是出于类推的目的而使用它。)在构造函数期间,设置了'abs'的值,所以我想知道是否在C结构,即使没有构造函数,也可以做同样的事情

typedef struct Comp
{
 double real;
 double imag;
 double abs;
} Comp;

int main(void)
{
 Comp z;
 z.real = 2.0f;
 z.imag = 5.3f;
 printf("%f\n" , z.abs);
}

因此,我希望能够在那里运行代码,并使其返回z.abs的值,而无需实际将其设置为任何值(尽管在同时设置z.real和z.imag之后将其设置为某些值) 。 在C中以某种方式可行吗?

编辑:我已经按照建议将其作为C结构中的默认值,在这个问题中,他们似乎想要自己的类型为默认值,所以该类型是预设的,但就我而言,我希望能够要做的是,不是将自定义类型设置为默认值,而是每次设置自定义类型时,将使用其中的一个属性“ z.abs”使用“ z.real”和“ z.imag”进行设置而不是使用默认值,例如:

Comp z;
z.real = 4.0f;
z.imag = 3.0f;

编写此代码后,将z定义为{4.0f,3.0f,null / undefined},但可以使用前两个作为sqrt(z.real ^ 2 + z.imag)来计算其最后一部分“ abs” ^ 2),因此它的值为5.0f。 因此,我希望在设置前两个数字之后,像第一个示例中的C#中的构造函数那样自动计算第三个数字。

给定您的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#中最好的样式。 相关的变化是,您的类现在仅具有字段而不是属性,并且您可以在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#中的属性总是转换为方法-getter和setter。 在您的示例中,您使用的是自动属性 ,这意味着,由于您没有为getter和setter指定函数主体,因此会为您自动创建一个默认主体,只需访问一个私有字段即可。

C语言中没有这样的东西,但是您可以手动创建相同的东西,下面是一个示例。

注意,我对语义进行了一些更改,因为在不更新abs的情况下就可以更改realimag ,因为这在您的C#代码中就是这种情况,这可能不是最明智的选择。

还要注意,对于这个小例子来说,这是完全矫kill过正的,我只是添加它来说明如何用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);
}

如果未在结构中显式设置字段,则其内容未指定。

您可以按以下方式初始化该结构的值:

Comp z = { 0.0, 0.0, 0.0 };

如果要将新struct “初始化”为一些预定值,其中某些必须从其他成员的值计算而来,则可以使用返回struct

#include <stdio.h>
#include <math.h>

typedef struct Comp
{
 double real;
 double imag;
 double abs;
} Comp;

Comp new_Comp(double re, double im);

int main(void)
{
    Comp my_comp = new_Comp(3.0, 4.0);

    printf("my_comp.real = %f, my_comp.imag = %f, my_comp.abs = %f\n",
           my_comp.real, my_comp.imag, my_comp.abs);

    return 0;
}

Comp new_Comp(double re, double im)
{
    Comp new = { .real = re, .imag = im };
    new.abs = hypot(re, im);

    return new;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM