我在C中工作,并且有一些我不想成为全局的变量,但我确实想要获取和设置可以在文件外部访问“Globaly”的方法。我习惯在Java中这样做,但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 :(得分:11)
您创建变量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);
文件名:header.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 :(得分:7)
如果你想在c中使用私有变量,有许多技术可以近似私有变量,但是C语言实际上没有“保护”概念,它扩展到私有,公共,受保护(如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功能时,你会添加更多的胶水代码(直到 更简单)实际使用面向对象的编程语言)。
答案 2 :(得分:2)
您可以输入:
static int c;
这样,“。o”将不会导出“c”变量。
答案 3 :(得分:1)
根据您的示例,您可以尝试使用一些struct
来获取此信息。 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风格”约定一样接近。
答案 4 :(得分:1)
static int c;
int get(void) {
return c;
}
int set(int n) {
c = n;
}
答案 5 :(得分:0)
您可以通过使用函数指针来改善@RageD的答案:
#ifndef MYCLASS_H
#define MYCLASS_H
/********************************* MyClass.h **********************************/
typedef struct MyClass {
int Value;
int (*GetValue)(); // Don't specify arguments
void (*SetValue)(); // Don't specify arguments
} MyClass_t;
// Make the default class accessible to other modules
extern MyClass_t new_MyClass;
#endif
/********************************* MyClass.c **********************************/
#include <stdio.h>
static int getValue(MyClass_t* obj){
if(obj == NULL)
return -1;
return obj->Value;
}
static void setValue(MyClass_t* obj, int value){
if(obj == NULL)
return;
obj->Value = value;
}
// Default "constructor" of MyClass
MyClass_t new_MyClass = {0, &getValue, &setValue};
/*********************************** main.c ***********************************/
#include "MyClass.h"
int main(){
// Create a default instance of the class
MyClass_t myClass = new_MyClass;
// Call the private (static) Getter function --> Prints 0
printf("%d\n", (*myClass.GetValue)(&myClass));
// Set the instance's value by the Setter function
(*myClass.SetValue)(&myClass, 9);
// Prints 9
printf("%d\n", (*myClass.GetValue)(&myClass));
return 0;
}