簡體   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