2012-04-25 64 views
7

我在C中工作,並有一些變量,我不想成爲全局變量,但我確實希望爲他們獲取和設置可以在「Globaly」外部訪問的方法的文件。我習慣在Java中這樣做,但C在這方面非常不同。基本上我正在尋找這個僞代碼之後的東西,但是我沒有能夠在任何地方找到我可能會看到的例子。C私有變量獲取和設置方法

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 2012-04-25 16:40:40

+0

因此我的問題。我如何欺騙C? – Reid 2012-04-25 16:41:18

+0

這取決於你想要做什麼。由於'C'不是OOP(它是面向函數的),你將不得不使用函數和'結構'或全局變量。 – RageD 2012-04-25 16:43:34

回答

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); 

文件名:報頭。ç

#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()'。 - 這就是您首先創建標題的原因。 – 2017-01-18 09:38:47

+2

不需要在頭文件中包含'stdio.h'。 - 標題中的代碼不使用它。 – 2017-01-18 09:39:58

+1

'header.c' - 大聲笑 – 2017-01-18 09:40:16

2

您可以鍵入:

static int c; 

這樣一來, 「.O」 不會出口 「C」 變量。

+0

那麼我能夠從get和set函數中訪問它,但不能直接訪問它嗎? IE瀏覽器。 'static'是否改變變量的範圍? – Reid 2012-04-25 16:43:03

+1

'static'使得一個全局變量只在它聲明的模塊內可見。例如,如果另一個模塊執行'extern int c',鏈接器將無法找到「c」。 – user1202136 2012-04-25 16:44:35

7

如果你想在c中使用私有變量,有許多技術可以接近一個私有變量,但是C語言實際上沒有一個擴展到private,public,protected的「保護」概念(如C++一樣)。

C的溫度將顯示任何變量(這是一個在C要求)的所以你必須與信息隱藏類型的變量(決策提領相當困難的)想法接近它。

一個竅門是限定的變量作爲void*與實際變量的類型僅在一個.c模塊是已知的。

/* 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". 

更好的方法是使用struct關鍵字來擴展這一理念,使僞方法,像這樣

/* 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; 
} 

說這樣的方法有幾個變種,一個是有一個「公共結構「帶有指向」私有結構「的void *指針。一種是將「方法」作爲函數指針包含在「公共結構」(支持多態的一個步驟)中,一種是實際編寫一個完整且正確的C++類型系統,試圖按照C++的原則來解析事物(類層次結構,多態性,後期綁定,信息隱藏等)。基本上,你可以在沒有太多工作的情況下獲得一些「面向對象的內核」,但是當你添加更多的-ornamentation特性時,你將會添加更多的膠水代碼(直到它實際上更容易使用面向對象的編程語言)。

+1

是否正確:typedef Person struct s_person; ?這將是:typedef結構s_person個人,對吧? – 2016-03-15 03:00:37

1

你的榜樣,你可以嘗試使用一些struct這些信息。 A struct就像class只有公開成員變量(即沒有功能)。因此,考慮的東西如下

#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; 
} 

正如你所看到的,C僅適用對象和函數。但要獲得所有文件的全局變量,請嘗試使用static int c = 0;

上面的示例幾乎儘可能接近「java樣式」約定。

1
static int c; 

int get(void) { 
    return c; 
} 

int set(int n) { 
    c = n; 
}