C和C++中static、不同源文件中成员和函数的互相访问的比较

1.static是C和C++中比较重要的关键字,某些情况下它在C和C++中的作用是相同的,首先讨论下它们作用相同的地方:

  1)当static在C和C++中修饰函数中的局部变量时,编译器将改变它的存储形式,被修饰的变量和生命周期不会随着函数的退出而消亡。

         2)当static在C和C++中修饰函数和全局变量时,可以简单的把它理解为private。下面写个简单的例子:

first.c:

#include <stdio.h>

int i;
void sayhello(){
   
   i=10;
   printf("In the first c file i=%d\n",i);
   printf("Hello World!\n");
}

second.c

#include <stdio.h>

extern int i;
int main(){

	i=20;
	printf("In the main function i=%d\n",i);
	sayhello();
	return 0;
}
用gcc编译这两个文件:  gcc first.c second.c  然后运行a.out ,结果为:

In the main function i=20
In the first c file i=10
Hello World!

如果你将first.c中的i和sayhello都声明为static之后,再编译,这个时候会报错:

second.c:(.text+0xb): undefined reference to `i'
second.c:(.text+0x15): undefined reference to `i'
second.c:(.text+0x2b): undefined reference to `sayhello'

私有化之后的变量和函数将不再可见,second.c中找不到它的定义。


2.在C++中static还有其特有的用法(主要体现在类变量和类函数中)

   如果一个类中的某个成员或者函数用static修饰,那么此类成员和函数将被类和类的实例所共有。

person.h

#include <iostream>
#include <string>
using namespace std;

class person{

	public:
	       static int id;
		string name;
		static void say();
		person();
		person(string name);
};

person.cpp

#include "person.h"

person::person(){}
person::person(string name):name(name){}

int person::id=10;

void person::say(){

	cout<<"Hello everyone,Thank you for reading!"<<endl;
}

main.cpp

#include "person.h"

int main(){

	person p;
	person p1("caige");
	person::say();
	p.say();
	p1.say();
	cout<<"In person p,person id="<<p.id<<endl;
	cout<<"In person p1:person id="<<p1.id<<endl;
	cout<<"In person,id="<<person::id<<endl;
	return 0;
}
用g++编译这两个文件:  g++ person.cpp main.cpp 然后运行a.out ,结果为:

Hello everyone,Thank you for reading!
Hello everyone,Thank you for reading!
Hello everyone,Thank you for reading!
In person p,person id=10
In person p1:person id=10
In person,id=10

在这里需要注意的是static修饰的类成员和函数的初始化。对于person中的id,其只能在定义的时候初始化,并且不能在类中初始化。

如果在person.h中把static int id; 更改为satic int id=10;则会报错(如果改为const static int id=10则不会报错):

In file included from person.cpp:1:0:
person.h:8:23: 错误:ISO C++ 不允许在类内初始化非常量静态成员‘id’
In file included from main.cpp:1:0:
person.h:8:23: 错误:ISO C++ 不允许在类内初始化非常量静态成员‘id’

另外在person.cpp中初始化id变量和say()函数时,其前面一定不能加static,虽然在类中声明的时候其前面都有sattic。其报错信息如下:

person.cpp:6:20: 错误:与声明不同,定义静态数据成员时不能使用‘static’ [-fpermissive]
person.cpp:8:25: 错误:不能将成员函数‘static void person::say()’声明为有静态链接 [-fpermissive]


satic还可以用来把一个class声明为内部存储类,在这里不多作说明!!!



3.关于不同源文件中成员和函数的互相访问的比较

   这个标题有点绕口,如果您有耐心读到这里并且读完,我相信您一定不会后悔的!

   用上面写的两个c源文件first.c和second.c来举例说明,在first.c中我声明了sayhello()函数,在second.c中我并没有写extern void sayhello(),

但是它却可以正常的调用first.c中的sayhello()函数。在C++中如果没有extern void sayhello();这条语句是会报错的!!!报错信息:

second.c: 在函数‘int main()’中:
second.c:8:11: 错误:‘sayhello’在此作用域中尚未声明

C++的编译器压根就不知道sayhello()是什么玩意儿。


另外,如果一个C++源文件要引用另一个C++源文件中的类(非satic),则必须在此源文件中复制类的所有声明,不需复制实现!用上面的例子说明:

将上面的person.cpp和main.cpp改成下面这样:

改版person.cpp

#include <iostream>
#include <string>
using namespace std;

class person{

	public:
	       static int id;
		string name;
		static void say();
		person();
		person(string name);
};

person::person(){}
person::person(string name):name(name){}

int person::id=10;

void person::say(){

	cout<<"Hello everyone,Thank you for reading!"<<endl;
}

改版main.cpp

#include <iostream>
#include <string>
using namespace std;

class person{

	public:
	       static int id;
		string name;
		static void say();
		person();
		person(string name);
};

int main(){

	person p;
	person p1("caige");
	person::say();
	p.say();
	p1.say();
	cout<<"In person p,person id="<<p.id<<endl;
	cout<<"In person p1:person id="<<p1.id<<endl;
	cout<<"In person,id="<<person::id<<endl;
	return 0;
}
用g++编译这两个源文件: g++ person.cpp main.cpp,结果为:

Hello everyone,Thank you for reading!
Hello everyone,Thank you for reading!
Hello everyone,Thank you for reading!
In person p,person id=10
In person p1:person id=10
In person,id=10

注意main.cpp中只是copy了person.cpp中关于person的定义,而没有copy其实现。但是其能正常的编译和运行。(没有用person.h)


C和C++源文件中互相访问各自的函数是有差别的,C中可以省略extern语句,C++不能省略。为了养成一个良好的编程习惯,写代码

的时候还是尽量把extern语句加上。要始终记住:所有编程语言中的变量和函数都必须是先定义后使用!

 

11月20日新增:

C和C++中关于strcut中的一点小小差别:

#include <stdio.h>

struct person{

    int name;
    int id;
};

int main(){

    typedef struct person person;
    person p;
    printf("%d\n",p.name);
}

 

#include <iostream>

struct person{

    int name;
    int id;
};

int main(){

    person p;
    std::cout<<p.name<<std::endl;
    return 0;
}

在第一段代码中如果没有typedef struct person person;这条语句,编译的时候将会报错!而C++中则没有如此严格的要求!

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值