在C中我们可以使用运算符,例如::或 - >访问头文件中的预定义方法?

时间:2011-05-23 17:06:31

标签: c++ c

我将有两个文件。一个header.h文件和第二个文件是main.c文件。

现在,如何使用C语言编写的header.h文件(例如打印测试等),然后在main.c文件中,如何使用::等运算符访问它们->

@file:main.c

#include "header.h"; // sorry i made mistake before

int main()
    {
      A::myStaticFunction();

      // OR

      A->myInstanceFunction();

      return 0;
    }

6 个答案:

答案 0 :(得分:4)

  

我想在C中完全做到这一点   (来自@ Sonia对@Als回答的评论)

不完全可能。你得到的是C ++代码,不能用C语言模拟它。

在C中,struct不能有函数,只能有函数指针,也不能有任何 static成员。所以,在这方面你没有::。另一个例子,@ David的回答,很可能是enum

typedef enum _H323Connection{
  AnswerCallNow,
  AnswerCallLater,
  IgnoreCall,
  /* examples */
}H323Connection;

现在,要在枚举中获取其中一个值,您可以使用名称(IgnoreCall)或使用枚举名称(H323Connection::IgnoreCall)对其进行限定。

然而,->运算符是完全可能的。

typedef struct _sA{
  // function pointer
  void (*AnswerCall)(struct _sA*, H323Connection);
  // variables...
}sA;

void sA_AnswerCall(sA* self, H323Connection callmode){
  // do something with self
  switch(callmode){
    case AnswerCallNow: /* ... */ break;
    case AnswerCallLater: /* ... */ break;
    case IgnoreCall: /* ... */ break;
  }
}

int main(){
  sA* pA = (sA*)malloc(sizeof(sA));

  // assign function pointer;
  pA->AnswerCall = sA_AnswerCall;
  // call it and pass "this" (the object the function operates on)
  pA->AnswerCall(pA, H323Connection::AnswerCallNow);
  // in C++ ---- ^^ would be the "this" pointer and 
  // would be passed secretly by the compiler

  free(pA);
}

答案 1 :(得分:3)

如果您的问题与->::运营商有关,则会以不同的方式使用它们。

首先是::运算符,它以两种方式使用

  1. 命名空间说明。 ::运算符用于在没有using关键字的情况下在命名空间内指定内容。例如,如果您使用的是vector<T>类的STL版本,则可以使用std::vector<T>
  2. 直接访问它
  3. 静态类成员访问权限。如果您为类(函数或变量)声明了静态成员,则可以通过ClassName::memberName访问它们。
  4. 其次,->运算符与.运算符相同,除了它用于指针对象。实施例

    struct myStruct {
        int x,y;
    };
    
    int main(void)
    {
        myStruct aStaticVersion;
        aStaticVersion.x = 0;
        myStruct *aPointerVersion = new myStruct();
        aPointerVersion->x = 0; //Acts the same as aStaticVersion.x = 0;
        return 0;
    }
    

    编辑:

    正如Xeo提醒我的那样,::运算符有第三种用法,用于指定enum EX的成员:

    enum myEnum {
      firstValue = 0,
      secondValue,
      thirdValue
    };
    
    int main(void)
    {
       myEnum enumValue = myEnum::secondValue;
       return 0;
    }
    

答案 2 :(得分:2)

你应该从C教程开始,因为这是非常基础的,并且肯定在所有教程中都有解释。

// header.h
#ifndef HEADER_H
#define HEADER_H
void foo();
#endif

// main.c
#include "header.h"
int main() {
   foo();
}

foo 定义在另一个链接在一起的.c文件中

现在看来,从代码中看,你不是在谈论C,而是C ++,并且你在标题中定义了一个类:

// header.h
#ifndef HEADER_H
#define HEADER_H
struct A {
   static void foo();
   void bar();
};
#endif

// main.c
#include "header.h"
int main() {
   A::foo();        // static method
   A a;
   a.bar();         // non-static method
}

再次,在.cpp文件中定义并链接在一起的方法。

答案 3 :(得分:2)

A::myStaticFu nction();`如果myStaticFunction()是A类中的静态函数,则是可能的。

A->myInstanceFunction();是不可能的,你需要创建一个A类指针来以这种方式调用它的成员函数。

// header.h

#ifndef HEADER_H
#define HEADER_H
class A
{
    public:
    static void myStaticFunction()
    {
         //do some stuff
    }

    void myInstanceFunction()
    {

    }
};

void doSomething()
{

}
#endif

//main.cpp

int main()
{
    //Call static function inside a class, no need of class instance or pointer
    A::myStaticFunction();

    //Call member function inside a class, need a class instance or pointer
    A *ptr = new A();
    ptr->myInstanceFunction();
    //or
    A obj;
    obj.myInstanceFunction()

    //call a global function outside the class, no need of class instance or pointer
    doSomething();

    return 1;
}

答案 4 :(得分:2)

::是范围解析运算符...您可以使用它来使用类似namespace::variable_name的语法在C ++中使用范围/命名空间创建限定名称。例如,如果你有

int a_var;

namespace nested
{
    int a_var;
}

然后,为了访问a_var的两个不同版本的完全限定名称,您将拥有::a_var(意味着它在全局范围内)和nested::a_var。如果您尝试调用名为a_var的变量,C ++将首先默认为当前范围。如果您想在另一个名称空间中获得另一个版本的a_var,则必须限定该名称。下面是使用您可能在上面的代码之后定义的两个函数的示例:

void func_a()
{
    a_var = 5; //<== accesses ::a_var in the global namespace
}

void func_b()
{
    nested::a_var = 5; <== accesses nested::a_var and not ::a_var
}

因此,您可以看到只将值5分配给a_var,但却无法获得a_var命名空间中nested的版本。如果您想要a_var的备用版本,则必须使用范围解析运算符来限定名称。

范围解析也适用于类和结构......这两种类型的对象都为它们的静态数据成员和函数创建了命名空间范围,所以如果你声明了一些对象class Foo,那么你想要访问某些静态数据成员int b_var,您可以通过编写完全限定名称Foo::b_var来获取对该成员的访问权。

->运算符是复合类型(即类和结构)的指针解引用运算符。我的工作方式与传统C中的工作方式相同,如果你有一个指向某种类型T对象的指针,那么T->method_function()T->non_static_variable将取消引用类型为{{1}的指针并访问适当的非静态成员函数或非静态数据变量。它与撰写T*(*T).method_function()基本相同。

答案 5 :(得分:0)

在C和派生中,您包含带有#include预处理器指令的头文件。除了解释包含的文件之外别无其他。这与将头文件的内容复制粘贴到源代码中的效果相同。 您无法按名称访问头文件或部分文件,例如在python中。