[英]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
的情況下就可以更改real
和imag
,因為這在您的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.