2012-04-25 66 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; 
}