c语⾔item变量,C++中的Item是什么关键字?可以定义什么型
的变量?
匿名⽤户
1级
2011-11-04 回答
NEW是C 的关键字,能进⾏类型的检查之类的
malloc是C跟C 都可以⽤的
不能进⾏类型检查之类
如果是在C 中,推荐使⽤new
inline函数区别与普通函数在于调⽤普通函数时程序有压栈和出栈操作,⽽inline(内联)函数编译器在预处理的时候会把它的代码加到调⽤它的函数中,⽽不⽤额外的跳转操作,从⽽提⾼了程序的效率。
但是inline不允许有switch, 循环等复杂语句。
堆,可⽤NEW对它分配内存,DELETE销毁内存空间。
栈,是由程序本⾝建⽴,分配,消除的内存空间!他服从先进后出(FILO)的原则,从⽽可以把各个变量按⽣存期分开!
static 声明的变量在C语⾔中有两⽅⾯的特征:
1)、变量会被放在程序的全局存储区中,这样可以在下⼀次调⽤的时候还可以保持原来的赋值。这⼀点是它与堆栈变量和堆变量的区别。
2)、变量⽤static告知编译器,⾃⼰仅仅在变量的作⽤范围内可见。这⼀点是它与全局变量的区别。
Tips:
A.若全局变量仅在单个C⽂件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C.设计和使⽤访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重⼊问题;
D.如果我们需要⼀个可重⼊的函数,那么,我们⼀定要避免函数中使⽤static变量(这样的函数被称为:带“内部存储器”功能的的函数)
E.函数中必须要使⽤static变量情况:⽐如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
函数前加static使得函数成为静态函数。但此处“static”的含义不是指存储⽅式,⽽是指对函数的作⽤域仅局限于本⽂件(所以⼜称内部函数)。使⽤内部函数的好处是:不同的⼈编写不同的函数时,不⽤担⼼⾃⼰定义的函数,是否会与其它⽂件中的函数同名。
扩展分析:术语static有着不寻常的历史.起初,在C中引⼊关键字static是为了表⽰退出⼀个块后仍然存在的局部变量。随后,static在C中有了第⼆种含义:⽤来表⽰不能被其它⽂件访问的全局变量和函数。为了避免引⼊新的关键字,所以仍使⽤static关键字来表⽰这第⼆种含义。最后,C 重⽤了这个关键字,并赋予它与前⾯不同的第三种含义:表⽰属于⼀个类⽽不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相同)。
全局变量、静态全局变量、静态局部变量和局部变量的区别变量可以分为:全局变量、静态全局变量、静态局部变量和局部变量。
按存储区域分,全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区。
按作⽤域分,全局变量在整个⼯程⽂件内都有效;静态全局变量只在定义它的⽂件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配⼀次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本⾝就是静态存储⽅式, 静态全局变量当然也是静态存储⽅式。 这两者在存储⽅式上并⽆不同。这两者的区别虽在于⾮静态全局变量的作⽤域是整个源程序, 当⼀个源程序由多个源⽂件组成时,⾮静态的全局变量在各个源⽂件中都是有效的。 ⽽静态全局变量则限制了其作⽤域, 即只在定义该变量的源⽂件内有效, 在同⼀源程序的其它源⽂件中不能使⽤它。由于静态全局变量的作⽤域局限于⼀个源⽂件内,只能为该源⽂件内的函数公⽤, 因此可以避免在其它源⽂件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储⽅式即改变了它的⽣存期。把全局变量改变为静态变量后是改变了它的作⽤域, 限制了它的使⽤范围。
static函数与普通函数作⽤域不同。仅在本⽂件。只在当前源⽂件中使⽤的函数应该说明为内部函数(static),内部函数应该在当前源⽂件中说明和定义。对于可在当前源⽂件以外使⽤的函数,应该在⼀个头⽂件中说明,要使⽤这些函数的源⽂件要包含这个头⽂件
static全局变量与普通的全局变量有什么区别:static全局变量只初使化⼀次,防⽌在其他⽂件单元中被引⽤;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化⼀次,下⼀次依据上⼀次结果值;
static函数与普通函数有什么区别:static函数在内存中只有⼀份,普通函数在每个被调⽤中维持⼀份拷贝
全局变量和静态变量如果没有⼿⼯初始化,则由编译器初始化为0。局部变量的值不可知。
C 中extern “C”含义深层探索
1.引⾔
C 语⾔的创建初衷是“a better C”,但是这并不意味着C 中类似C 语⾔的全局变量
和函数所采⽤的编译和链接⽅式与C 语⾔完全相同。作为⼀种欲与C 兼容的语⾔,C 保留了
⼀部分过程式语⾔的特点,因⽽它可以定义不属于任何类的全局变量和函数。但是,C 毕竟
是⼀种⾯向对象的程序设计语⾔,为了⽀持函数的重载,C 对全局函数的处理⽅式与C 有明
显的不同。
2.从标准头⽂件说起
某企业曾经给出如下的⼀道⾯试题:
⾯试题
为什么标准头⽂件都有类似以下的结构?
#ifndef _TEST_H
#define _TEST_H
#ifdef __cplusplus
extern "C" {
#endif
/
*...*/
#ifdef __cplusplus
}
#endif
#endif /* _TEST_H */
分析
显然,头⽂件中的编译宏“#ifndef _TEST_H、#define _TEST_H、#endif” 的作⽤是防⽌
该头⽂件被重复引⽤。
那么
#ifdef __cplusplus
static修饰的变量
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
的作⽤⼜是什么呢?
3.深层揭密extern "C"
extern "C" 包含双重含义,从字⾯上即可得到:⾸先,被它修饰的⽬标是“extern”的;其次,被它修饰的⽬标是“C”的。让我们来详细解读这两重含义。
被extern "C"限定的函数或变量是extern 类型的;
extern 是C/C 语⾔中表明函数和全局变量作⽤范围(可见性)的关键字,该关键字告
诉编译器,其声明的函数和变量可以在本模块或其它模块中使⽤。记住,下列语句:
extern int a;
仅仅是⼀个变量的声明,其并不是在定义变量a,并未为a 分配内存空间(特别注意:实
际上现在⼀般的编译器都会对上述语句作声明处理,但链接器在链接过程中如果没有发现该变量的定义,⼀般会在第⼀次遇到该变量声明的地⽅,⾃动定义)。变量a 在所有模块中作为⼀种全局变量只能被定义⼀次,否则会出现连接错误。
通常,在模块的头⽂件中对本模块提供给其它模块引⽤的函数和全局变量以关键字
extern 声明。例如,如果模块B 欲引⽤该模块A 中定义的全局变量和函数时只需包含模块A 的头⽂件即可。这样,模块B 中调⽤模块A 中的函数时,在编译阶段,模块B 虽然不到该函数,但是并不会报错;它会在连接阶段中从模块A 编译⽣成的⽬标代码中到此函数。
与extern 对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使⽤。因
此,⼀个函数或变量只可能被本模块使⽤时,其不可能被extern “C”修饰。
被extern "C"修饰的变量和函数是按照C 语⾔⽅式编译和连接的;
未加extern “C”声明时的编译⽅式
⾸先看看C 中对类似C 的函数是怎样编译的。
作为⼀种⾯向对象的语⾔,C ⽀持函数重载,⽽过程式语⾔C 则不⽀持。函数被C 编
译后在符号库中的名字与C 语⾔的不同。例如,假设某个函数的原型为:
void foo( int x, int y );
该函数被C 编译器编译后在符号库中的名字为_foo,⽽C 编译器则会产⽣像
_foo_int_int 之类的名字(不同的编译器可能⽣成的名字不同,但是都采⽤了相同的机制,
⽣成的新名字称为“mangled name”)。
_foo_int_int 这样的名字包含了函数名、函数参数数量及类型信息,C 就是靠这种机制
来实现函数重载的。例如,在C 中,函数void foo( int x, int y )与void foo( int x, float
y )编译⽣成的符号是不相同的,后者为_foo_int_float。
同样地,C 中的变量除⽀持局部变量外,还⽀持类成员变量和全局变量。⽤户所编写程序的类成员变量可能与全局变量同名,我们以"."来区分。⽽本质上,编译器在进⾏编译时,与函数的处理相似,也为类中的变量取了⼀个独⼀⽆⼆的名字,这个名字与⽤户程序中同名的全局变量名字不同。
未加extern "C"声明时的连接⽅式
假设在C 中,模块A 的头⽂件如下:
// 模块A 头⽂件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
int foo( int x, int y );
#endif
在模块B 中引⽤该函数:
// 模块B 实现⽂件 moduleB.cpp
#i nclude "moduleA.h"
foo(2,3);
实际上,在连接阶段,连接器会从模块A ⽣成的⽬标⽂件moduleA.obj 中寻
_foo_int_int 这样的符号!
加extern "C"声明后的编译和连接⽅式
加extern "C"声明后,模块A 的头⽂件变为:
// 模块A 头⽂件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
extern "C" int foo( int x, int y );
#endif
在模块B 的实现⽂件中仍然调⽤foo( 2,3 ),其结果是:
(1)模块A 编译⽣成foo 的⽬标代码时,没有对其名字进⾏特殊处理,采⽤了C 语⾔的
⽅式;
(2)连接器在为模块B 的⽬标代码寻foo(2,3)调⽤时,寻的是未经修改的符号名_foo。如果在模块A 中函数声明了foo 为extern "C"类型,⽽模块B 中包含的是extern int
foo( int x, int y ) ,则模块B 不到模块A 中的函数;反之亦然。
所以,可以⽤⼀句话概括extern “C”这个声明的真实⽬的(任何语⾔中的任何语法特
性的诞⽣都不是随意⽽为的,来源于真实世界的需求驱动。我们在思考问题时,不能只停留在这个语⾔是怎么做的,还要问⼀问它为什么要这么做,动机是什么,这样我们可以更深⼊地理解许多问题):
实现C 与C 及其它语⾔的混合编程。
明⽩了C 中extern "C"的设⽴动机,我们下⾯来具体分析extern "C"通常的使⽤技巧。
< "C"的惯⽤法
(1)在C 中引⽤C 语⾔中的函数和变量,在包含C 语⾔头⽂件(假设为cExample.h)
时,需进⾏下列处理:
extern "C"
{
#i nclude "cExample.h"
}
⽽在C 语⾔的头⽂件中,对其外部函数只能指定为extern 类型,C 语⾔中不⽀持extern "C"声明,在.c ⽂件中包含了extern "C"时会出现编译语法错误。
笔者编写的C 引⽤C 函数例⼦⼯程中包含的三个⽂件的源代码如下:
/* c 语⾔头⽂件:cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y);
#endif
/* c 语⾔实现⽂件:cExample.c */
#i nclude "cExample.h"
int add( int x, int y )
{
return x y;
}
// c 实现⽂件,调⽤add:cppFile.cpp
extern "C"
{
#i nclude "cExample.h"
}
int main(int argc, char* argv[])
{

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。