1. C++/C的项目里怎么共享“全局变量”呢
全局变量定义时,如果不加static修饰,那么作用域就是整个项目,可以在任何一个文件中访问或修改。
不过直接在其它文件中引用该变量时,会报未定义错误,需要在调用文件进行声明。
声明格式为:
类型 变量名;
注意声明时不能有赋值操作,否则就会被认定为是新的定义,导致重复定义错误出现。
下面是一个例子。
在a.c中,定义全局变量gvar,类型为int,初始化值为3.
int gvar = 3;
在同一个项目的b.c中,声明gvar,同时定义一个函数,使gvar自加,并打印gvar的值:
externintgvar;//加extern声明可以使读到代码的人知道,这是一个外部文件定义的全局变量,但在C/C++中,该关键字并非强制,不加也不会出错。
voidfunc(void)
{
gvar++;//gvar自加,也就是改变值的操作。
printf("%d ",gvar);//输出gvar,也就是引用其值的操作。
//以上两个操作表明,在这个文件中,gvar是可被读写的。
}
2. C语言中如何定义全局变量
众所周知,全局变量在被定义后,系统会为全局变量分配内存并且它还可以被其他模块通过C语言中extern关键字调用。这样就必须在 xx.C 和xx.H 文件中定义。这种重复的定义很容易导致错误。 下面是只需用在头文件中定义一次就可以在别的模块使用的定义方法。
格式: 定义全局宏。
#ifdef xxx_GLOBALS
#define xxx_EXT#else#define xxx_EXT extern
#endif 上面位于.H 文件中,每个全局变量都加上了xxx_EXT的前缀,xxx代表模块的名字。该模块的.C文件中有以下定义:#define xxx_GLOBALS
当编译器处理.C文件时,它强制xxx_EXT(在相应.H文件中可以找到)为空,(因为xxx_GLOBALS已经定义)。所以编译器给每个全局变量分配内存空间,而当编译器处理其他.C文件时,xxx_GLOBAL没有定义,xxx_EXT被定义为extern,这样用户就可以调用外部全局变量。进阶:在abc.H:#ifdef abc_GLOBALS
#define abc_EXT#else
#define abc_EXT extern#endif
abc_EXT unsigned int Ctr;
同时,abc.H有中以下定义:#define abc_GLOBALS
当编译器处理abc.C时,它使得头文件变成如下所示,因为abc_EXT被设置为空。unsigned int Ctr;
这样编译器就会将这些全局变量分配在内存中。当编译器处理其他.C文件时,头文件变成了如下的样子,因为abc_GLOBAL没有定义,所以abc_EXT被定义为extern。extern unsigned int Ctr;
在这种情况下,不产生内存分配,而任何 .C文件都可以使用这些变量。这样的就只需在 .H 文件中定义一次就可以了。
3. 怎么设置 linux环境变量配置
1、直接用export命令:
#export PATH=$PATH:/opt/au1200_rm/build_tools/bin
查看是否已经设好,可用命令export查看:
[root@localhost bin]# export
declare -x BASH_ENV="/root/.bashrc"
declare -x G_BROKEN_FILENAMES="1"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="localhost.localdomain"
declare -x INPUTRC="/etc/inputrc"
4. linux下,多个c的源文件共用一个全局变量的方法
你需要在其中一个*.c文件中定要该变量, 然后在其他*.c文件中引用该变量即可.
例如你在aaa.c中定义
int a=10;
在bbb.c中引用
extern int a;
就可以使用了.
但是如果你的变量很多,为了不让你在每个需要用的地方都加上上面这个语句
可以在aaa.h中声明上面这一句 extern int a;
然后在需要用到的*.c的开头加上下面这句即可
#include "aaa.h"
5. 如何声明线程私有全局变量
线程私有全局变量就是线程私有变量。
Linux下C语言是这么实现的,定义一个全局变量:pthread_key_t thread_key;
使用这个函数初始化:pthread_key_create(&thread_key,NULL);
然后在线程内调用这个函数存储线程私有变量:pthread_setspecific(thread_key,(void*)num);//num是要存储的数据的指针
在线程内的任意位置调用这个函数可以取得在这个线程内使用pthread_setspecific函数存进来的值,pthread_getspecific(thread_key);//取得num指针。
反正一共就3个API,实在不明白就去搜索一下线程私有变量的用法
6. 学习Linux的步骤是怎样的
对于Linux的学习,可以分为四个阶段,Linux初级入门阶段→Linux中级进阶→Linux高级进阶→Linux资深方向细化阶段
第一阶段:初级阶段
初级阶段需要把linux学习路线搞清楚,任何学习都是循序渐进的,所以学linux也是需要有一定的路线。
1. Linux基础知识、基本命令;
2. Linux用户及权限基础;
3. Linux系统进程管理进阶;
4. linux高效文本、文件处理命令;
5. shell脚本入门
第二阶段:中级进阶
中级进阶需要在充分了解linux原理和基础知识之后,对上层的应用和服务进行深入学习,其中说到服务肯定涉及到网络的相关知识,是需要花时间学习的。
1. TCP/IP网络基础;
2. Linux企业常用服务;
3. Linux企业级安全原理和防范技巧;
4. 加密/解密原理及数据安全、系统服务访问控制及服务安全基础;
5. iptables安全策略构建;
6. shell脚本进阶;
7. MySQL应用原理及管理入门
第三阶段:Linux高级进阶
1. http服务代理缓存加速;
2. 企业级负载集群;
3. 企业级高可用集群;
4. 运维监控zabbix详解;
5. 运维自动化学习;
第四阶段:Linux资深方向细化
1. 大数据方向;
2. 云计算方向;
3. 运维开发;
4. 自动化运维;
5. 运维架构师
以上是Linux的一个学习方向和路线,对于Linux学习是一个需要坚持的过程,也许通过自学或者培训,3至6个月都可以把基本知识学会,但是重在实践,深入的思考和不断的摸索,你会发现Linux更多的美!
7. LinuxC语言头里面的ERROR函数怎么使用
errno会返回一个数字,每个数字代表一个错误类型。详细的可以查看头文件。/usr/include/asm/errno.h
如何把errno的数字转换成相应的文字说明?
方式一:可以使用strerrno函数
char
*strerror(int
errno)
使用方式如下:
fprintf(stderr,"error
in
CreateProcess
%s,
Process
ID
%d
",strerror(errno),processID)
将错误代码转换为字符串错误信息,可以将该字符串和其它的信息组合输出到用户界面。
注:假设processID是一个已经获取了的整形ID
方式二:使用perror函数
void
perror(const
char
*s)
函数说明
perror
(
)用来将上一个函数发生错误的原因输出到标准错误(stderr),参数s
所指的字符串会先打印出,后面再加上错误原因
字符串。此错误原因依照全局变量
errno
的值来决定要输出的字符串。
另外并不是所有的c函数调用发生的错误信息都会修改errno。例如gethostbyname函数。
errno是否是线程安全的?
errno是支持线程安全的,而且,一般而言,编译器会自动保证errno的安全性。
我们看下相关头文件
/usr/include/bits/errno.h
会看到如下内容:
#
if
!defined
_LIBC
||
defined
_LIBC_REENTRANT
/*
When
using
threads,
errno
is
a
per-thread
value.
*/
#
define
errno
(*__errno_location
())
#
endif
#
endif
/*
!__ASSEMBLER__
*/
#endif
/*
_ERRNO_H
*/
也就是说,在没有定义__LIBC或者定义_LIBC_REENTRANT的时候,errno是多线程/进程安全的。
为了检测一下你编译器是否定义上述变量,不妨使用下面一个简单程序。
#include
<stdio.h>
#include
<errno.h>
int
main(
void
)
{
#ifndef
__ASSEMBLER__
printf(
"Undefine
__ASSEMBLER__/n"
);
#else
printf(
"define
__ASSEMBLER__/n"
);
#endif
#ifndef
__LIBC
printf(
"Undefine
__LIBC/n"
);
#else
printf(
"define
__LIBC/n"
);
#endif
#ifndef
_LIBC_REENTRANT
printf(
"Undefine
_LIBC_REENTRANT/n"
);
#else
printf(
"define
_LIBC_REENTRANT/n"
);
#endif
return
0;
}
8. linux源码中,.org 0x2000,ENTRY(pg1)表示的是什么意思org是什么意思,ENTRY是什么意思啊
.org 0x2000表示内容填充至地址0x2000。如:你的文件有0x1000字节,你指定链接器ld将该文件的内容加载到内存地址0x0000,这样文件最末就在地址0x0FFF上,你承认吧。如果在文件的末尾有.org 0x2000这条指令,就说明你要求汇编器用“0x0”填充从地址0x1000到0x2000的内容。 填充的内容可由你自己决定,默认应该是0x0。
ENTRY(pg1)是一个宏
1. .globl pg1
定义全局变量pg1(应该叫符号)。汇编器认为这个符号是唯一的,不能再有和它重名的符号。
2. pg1:
将该符号用作地址助记符。该地址是有程序员显示指定或者由链接器ld分配的。这样,如果程
序员需要用到该地址上的内容的时候就不需要知道地址的值是多少,而只需要使用符号pg1就
可以 了。
这种定义的形式和 C中的全局变量相同,但绝对不是全局变量。
9. linux下C语言,进程A定义全局数组A,进程B想读取进程A的数组A,这样跨进程访问全局变量可以吗
进程A可以把数组A的内容传给B进程,但是想让B进程直接访问A进程的A数组好像是不行的吧