2012-04-25 6 views
7

私はC言語で作業していますが、グローバルにしたくない変数をいくつか持っていますが、私はそれらのメソッドを取得して、 "Globaly"ファイルの私はJavaでこれを行うのに慣れていますが、Cはこのように非常に異なります。基本的に私はこの擬似コードに従うものを探していますが、私が見ているかもしれない例があればどこでも見つけることができませんでした。Cプライベート変数GetとSetメソッド

main.c 
#include data.h 
set(b); 

datalog.c 
#include data.h 
get(b); 

data.c 
private int c; 
set(b){ 
    c = b; 
} 
get(c){ 
    return c; 
} 
+0

'C'は' private'という概念を持っていません。たぶん '静的'グローバル変数を見てみよう。 – RageD

+0

私の質問です。どのように私はCをトリックできますか? – Reid

+0

それはあなたがしようとしていることによって異なります。 'C'はOOP(関数指向)ではないので、関数や' struct'やグローバル変数を扱わなければなりません。 – RageD

答えて

10

あなたは変数staticを作成します。グローバル変数がstaticになると、そのスコープは現在のファイルに制限されます。

ファイル名:main.cの

#include <stdio.h> 

#include "header.h" 

extern int get(); 
extern void set(int); 

int main() 
{ 
    set(10); 
    printf("value = %d \n", get()); 
    set(20); 
    printf("value = %d \n", get()); 
    set(30); 
    printf("value = %d \n", get()); 
    set(40); 
    printf("value = %d \n", get()); 
    return 0; 
} 

ファイル名:がheader.h

#include <stdio.h> 

int get(void); 
void set(int); 

ファイル名:ヘッダーを次のように

例です。C

#include "header.h" 

static int value = 0; 

int get(void) 
{ 
    return value; 
} 

void set(int new_value) 
{ 
    value = new_value; 
} 

出力:あなたの例により、

$ gcc -Wall -o main main.c header.h header.c 
$ ./main 
value = 10 
value = 20 
value = 30 
value = 40 
$ 
+1

'main.c'の先頭に' get() 'と' set() 'を宣言する必要はありません。 - これが最初にヘッダーを作成した理由です。 –

+2

ヘッダーに 'stdio.h'を含める必要はありません。 - ヘッダーのコードはそれを使用しません。 –

+1

'header.c' - lol –

2

次のように入力します。

static int c; 

この方法は、 "C" 変数をエクスポートしません "の.o"。

+0

getとset関数からこれにアクセスできますが、直接アクセスすることはできませんか? IE。 'static'変数のスコープを変更しますか? – Reid

+1

'static'はグローバル変数を宣言されているモジュールの内部でしか見ることができません。例えば、別のモジュールが 'extern int c'を実行した場合、リンカは「c」を見つけることができません。 – user1202136

7

プライベート変数をcに入れたいのであれば、プライベート変数に近似できる手法がいくつもありますが、C言語には実際にはprivate、public、protected(C++そうです)。

Cは、任意の変数の名前が表示されます(これはCでの要件です)ので、あなたは、変数(かなり難しい逆参照すること)のタイプの情報隠蔽のアイデアと、それに接近しなければなりません。

1つのトリックは、唯一の.cモジュールで知られている実際の変数の型とvoid*として変数を定義です。

/* somefile.h */ 

extern void* counter; 

/* somefile.c */ 

#include "somefile.h" 

int actualCounter = 0; 
void* counter = &actualCounter; 

/* otherfile.c */ 

#include "somefile.h" 

// we can see "counter", but we cannot "use" it here; because we don't have access 
// to the real "hidden" type of "int". 

より良い方法は、このような

/* person.h */ 

struct s_person; 

typedef Person struct s_person; 

Person* new_Person(char* name); 
void delete_Person(Person* person); 

void Person_setName(Person* person, char* name); 
char* Person_getName(Person* person); 

/* person.c */ 

struct s_person { 
    char* name; 
}; 

Person* new_Person(char* name) { 
    Person* object = (Person*)malloc(sizeof(struct s_person)); 
    // duplicate the string for more security, otherwise constructor 
    // could manipulate the "private" string after construction. 
    object->name = strdup(name); 
    return object; 
} 

void delete_Person(Person* person) { 
    // some implementations pass a Person** to set the reference to 0 
    // this implementation requires that the caller sets his own references to 0 
    free(person->name); 
    free(person); 
} 

void Person_setName(Person* person, char* name) { 
    // free the old 
    free(person->name); 
    // duplicate the new to provide "out of simulated class" modification by malicious 
    // name setter. 
    person->name = strdup(name); 
} 

char* Person_getName(Person* person) { 
    // must return a copy, otherwise one can manipulate name 
    // from reference provided by Person_getName(...); 
    return strdup(person->name); 
} 

/* otherfile.c */ 

#include "Person.h" 

/* Now we can hold Person "simulated objects", but we cannot */ 
/* manipulate their "state" without using the C simulated object */ 
/* methods */ 

int main(int argc, char** argv) { 

    Person* bob = new_Person("bob"); 
    printf("%s\n", Person_getName(bob)); 
    delete_Person(bob); 
    // critical or we hold a pointer to freed memory. 
    bob = 0; 

    return 0; 
} 

技術は、いくつかのバリエーションを持っているので、同様に、structキーワードを使用して、この考え方を拡張し、擬似メソッドを作ることで、1は「公共の構造体を持つことです"を" private struct "へのvoid *ポインタで置き換えます。 1つは、 "public struct"(多態性をサポートするためのステップ)に関数ポインタとして "メソッド"を含めることです。一つは実際にC++のようなものを正確に解決しようとする完全で適切なC++型システムを書くことです(クラス階層、レイトバインディング、情報隠蔽など)を含むことができる。

それが実際に使用することがはるかに簡単になるまで基本的に(、あなたはあまりにも多くの作業をせずに、いくつかの「オブジェクト指向ネス」を得ることができますが、あなたは-ornamentationのより多くの機能を追加すると、あなたはより多くのグルーコードを追加しますオブジェクト指向プログラミング言語)。

+1

正しいですか?typedef Person struct s_person; ?それは次のようになります:typedef struct s_person人、そうですか? –

1

、あなたはこの情報をいくつかstructを使用して試すことができます。 structclassのようなもので、publicメンバー変数(つまり機能なし)のみです。あなたは、唯一のオブジェクトや関数とC作品を見ることができるように

#include <stdio.h> 

typedef struct _somestruct 
{ 
    int c; 
} theStruct; 

int getC(theStruct* obj) 
{ 
    if(obj == NULL) 
    return -1; 
    return obj->c; 
} 

void setC(theStruct* obj, int val) 
{ 
    if(obj == NULL) 
    return; 
    obj->c = val; 
} 

int main() 
{ 
    theStruct myStruct; 
    setC(&myStruct, 5); 
    printf("%d\n", getC(&myStruct)); 
    return 0; 
} 

を次のように何かを考えます。しかし、すべてのファイルでグローバル変数を取得するには、static int c = 0;

上記の例は、「Javaスタイル」の規約に近い可能性があります。

1
static int c; 

int get(void) { 
    return c; 
} 

int set(int n) { 
    c = n; 
} 
関連する問題