[英]Not sure how to turn a Java class into a C header and code
我有以下java類:
class Rect {
int width;
int height;
Rect (int a, int b){
width = a;
height = b;
}
int area() {
return width * height;
}
}
但是我不確定如何將其轉換為C代碼。
到目前為止,我有這個:
標頭
#pragma once
struct rect {
int width, height;
};
int area();
頭文件
int area() {
//How do I access these?
//return width * height;
}
主要
#include "Header.h"
int main(int argc, char* argv[]) {
struct rect rect;
rect.height = 5;
rect.width = 10;
//How do I call rect.area() in here?
}
您不能在C
執行此操作,但是可以,您可以使用函數指針來模擬。 創建一個函數指針,然后為其分配功能area
。 (也許在一些初始化功能中)。 但是然后,您還必須做很多事情來清楚地模擬它。
例如,這里沒有this
概念。 因此,每次調用都必須傳遞結構的地址。 因此,不確定這將有多大幫助。
struct rect {
int width, height;
int (*f_area)(struct rect *);
};
int area(struct rect *p){
return p->width*p->height;
}
/*
This function dynamically allocates struct rect and returns
its address
*/
struct rect * get_rect(){
...
rect->f_area = area;
return rect;
}
這樣稱呼它
int ar = rectvar->area(&rectvar);
但是現在您可能會說這確實是愚蠢的事情。 但是C
無法滿足您的要求。 是的,就是這樣。
當您擴展一種語言以獲得沒有的功能時,事情就是這樣。 您可以像這樣簡單地使用區域功能-使您免於生活中的各種困難。
struct rect rv;
rv.height = 10;
rv.width = 20;
int ar = area(&rv);
int area(struct rect* r);
int area(struct rect* r) {
return r->width * r->height;
}
int main(int argc, char* argv[]) {
struct rect rect;
rect.height = 5;
rect.width = 10;
printf("Area: %d\n", area(&rect));
}
Basic C更喜歡傳遞指針。 一個面向對象的語言有一個隱含的參數, this
對每一個方法-這么說。
通常,該方法將標有“ class”:
int rect_area(struct rect* r);
具有結構和結構上的功能:
struct rect {
int width, height;
};
struct rect *new_rect(int w,int h) {
struct rect *this = malloc(sizeof struct rect); // should check bad alloc...
this->width = w;
this->height = h;
return this;
}
int area(struct rect *this) { // in a method, 'this' can be viewed as an implicit parameter...
return this->width*this->height;
}
int main(int argc, char* argv[]) {
struct rect *rect = new_rect(5,10);
area(rect);
// beware of memory leaks, should add some destructor...
}
C沒有提供從對象調用函數並使它對特定對象的數據進行操作的機制(即Java和C ++中的隱式this
指針)。 您必須在函數的參數列表中指定對象:
struct Rect {
int width;
int height;
};
int area( struct Rect r ) // struct keyword is necessary
{
return r.width * r.height;
}
int main( void )
{
struct Rect foo; // struct keyword is necessary
int a = area( foo );
...
}
在C語言中, struct
標記名稱本身並不能自動成為類型名稱-您必須使用struct Rect
聲明該類型的對象。 如果您想讓Rect
本身成為類型名稱,則必須使用typedef
工具:
typedef struct Rect Rect;
現在,您可以Rect
使用Rect
作為類型名稱:
Rect foo;
這個特定的示例按值傳遞struct Rect
對象-形式參數r
是內存中與實際參數foo
不同的對象,並且它接收foo
內容的副本。 這意味着對函數中的r.width
或r.height
所做的任何更改都不會反映在foo
。
如果您的函數需要修改foo
的內容,則需要向其傳遞一個指針:
void scale( struct Rect *r, int wscale, int hscale )
{
r->width *= wscale; // r->width equivalent to (*r).width
r->heignt *= hscale; // '->' implicitly dereferences pointer
} // before accessing member
int main( void )
{
struct Rect foo = {10, 10}; // initialize width and height to 10
...
scale( &foo, 2, 3 );
...
}
人們總是會通過指針傳遞struct
類型,因為創建大型struct
類型的副本可能會很昂貴。 如果你傳遞一個指針並不需要修改對象的功能,一定要限定它為const
:
int area ( const struct Rect *r ) { return r->width * r->height; }
這樣,如果您不小心嘗試寫入width
或height
,編譯器可能會對您大喊大叫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.