c++笔记(3):函数内联、重载、宏定义、static和extern、存储区域

来源:互联网 发布:android数独游戏源码 编辑:程序博客网 时间:2024/05/17 06:22
1.内联函数:编译器在编译时,将内联函数的调用以相应代码代替,内联函数仅在函数原型作一次声明。适用于只有1到5行的小函数不能含有复杂结构控制语句,不能递归调用

声明格式:inline  函数原型


2.函数重载:多个同名函数有不同的参数集,编译器根据不同参数的类型和个数产生调用匹配,函数重载用于处理不同数据类型的类似任务。

参数个数相同,参数类型不同
参数个数不同(使用默认参数时会出错)


3.

自动存储类变量存放在栈区,进入声明的块时生成,在结束块时删除。函数的参数和局部变量都是自动存储类,自动存储是变量的默认状态。


4.

关键字extern和static声明静态存储类变量或函数的标识符
extern和static说明变量时,程序开始执行时分配和初始化存储空间 
extern和static说明函数,表示从程序执行开始就存在这个函数名 
C++不对自动变量初始化,对静态变量默认初始化值为0
静态变量具有记忆性,其值等于上一次函数调用时保留的值

5.
具有文件作用域的变量称为全局变量;具有函数作用域或块作用域的变量称为局部变量
全局变量声明时默认初始值为0
当局部量与全局量同名,在块内屏蔽全局量
为了在块内访问全局量,可以用域运算符 " :: "

6.
# include  <文件名>
或# include  "文件名(自定义的头文件)"  

7.
条件编译:
# if  常量表达式
程序段
# endif
或者
# if  常量表达式
程序段1
# else
程序段2
# endif
或者
# if  常量表达式1
程序段1 
# elif  常量表达式2
程序段2

# elif  常量表达式n
程序段n
# else
程序段n+1

# endif


8.

宏定义指令:#define  标识符  文本 
//不带参数宏替换。在程序正文中,用3.1415926代替PI
#define PI  3.1415926
//带参数宏替换。在程序正文中,PI*r*r代替area(x),r是参数
#define area(r)  PI*r*r   
//不带参数的宏替换,在C++中使用常量定义:
const double PI=3.1415926;
//带参数宏替换,C++使用内联函数:
inline double area(double r) {return PI*r*r;}

#ifndef CALCULATE_H // 若CALCULATE_H未定义,执行下一宏指令#define CALCULATE_H      // 用后续3行正文代替CALCULATE_Hdouble circle(double radius){       const double pi = 3.14159 ;    return pi * radius * radius;}#endif

9.
命名空间:
std是C++的标准名空间,包含了标准头文件中各种名字的声明。
使用标准类库的组件时,需要指定名空间。 
使用标准名空间方法一:
#include<iostream>using namespace std;int main(){     int a, b;    cin>>a;    cin>>b;    cout<<"a+b="<<a+b<<'\n'; }
使用标准名空间方法二:
#include<iostream>using std::cin; using std::cout;int main(){     int a, b;    cin>>a;    cin>>b;    cout<<"a+b="<<a+b<<'\n'; }
使用标准名空间方法三:
#include<iostream>int main(){     int a, b;    std::cin>>a;    std::cin>>b;    std::cout<<"a+b="<<a+b<<'\n'; }
定义命名空间语法:
namespace <标识符>
{ <语句序列> }
int main(){     g() ;//调用非命名空间函数    using namespace A;//使用命名空间A    f() ;//调用命名空间函数A::f()     B::f() ;//调用函数A::B::f()     B::C::f() ;//调用函数A::B::C::f()     A::g() ;//调用函数A::g() }
10.
头文件的结构:头文件中只存放“声明”,不存放“定义”;为防止头文件的定义内容被重复引用,使用 ifndef/define/endif 结构产生预处理块。不提倡使用全局变量,尽量不要在头文件中出现如extern int value;这样的说明。

11.

对于一个文件,在main函数之外定义的变量叫全局变量,main函数或其它函数之内定义的变量叫做局部变量。

函数的参数和局部变量都是自动存储类变量,自动存储类是变量的默认状态,在进入声明的块时生成,在结束块时删除。用关键字extern和static声明的都是静态存储类变量。extern和static说明变量时,程序开始执行时分配和初始化存储空间,extern和static说明函数,表示从程序执行开始就存在这个函数名。

Static

(1)      修饰局部变量:在用static修饰局部变量后,该变量只在初次运行时进行初始化工作,且只进行一次。对于静态局部变量如果没有进行初始化的话,对于整形变量系统会自动对其赋值为0,对于字符数组,会自动赋值为'\0'.而且是静态的,不会因为作用域的结束而消亡即static不改变变量的作用域。

(2)      修饰全局变量:在全局变量前面加上关键字static,该全局变量变成了全局静态变量,该变量在本文件内从定义开始到文件结束可见(不可跨文件调用),该变量只在初次运行时进行初始化工作,且只进行一次。对于静态全局变量如果没有进行初始化的话,对于整形变量系统会自动对其赋值为0,对于字符数组,会自动赋值为'\0'.而且是静态的,不会因为作用域的结束而消亡即static不改变变量的作用域。

(3)      修饰函数:在函数返回类型前加上static关键字,函数即被定义为静态函数,static改变了函数的作用域(a.普通函数可以跨文件调用,静态函数只能在本源文件中使用b.在文件作用域中声明的inline函数默认为static类型)

(4)      C++中static:如果在C++中对类中的某个函数用static进行修饰,则表示该函数属于一个类而不是属于此类的任何特定对象;如果对类中的某个变量进行static修饰,表示该变量为类以及其所有的对象所有。它们在存储空间中都只存在一个副本。可以通过类和对象去调用。对于静态成员函数,只能访问静态成员函数和静态成员变量,不能访问非静态成员函数或者变量。

Extern

(1)      修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”,(可以申明多次,但是定义只能一次)对于一个全局变量,它既可以在本源文件中被访问到,也可以在同一个工程的其它源文件中被访问(只需用extern进行声明即可)。extern声明的位置对其作用域也有关系,如果是在main函数中进行声明的,则只能在main函数中调用,在其它函数中不能调用。其实要调用其它文件中的函数和变量,只需把该文件用#include包含进来即可,只不过因为用extern会加速程序的编译过程,能节省时间。

(2)      extern表示将变量或函数声明为外部链接,变量默认是内部链接,函数默认是外部链接。因此用来外部链接的函数,声明时有无extern都可以连接通过。而全局变量则不行。通常,在模块的头文件中,对本模块提供给其他模块引用的函数和全局变量以关键字extern声明。

(3)      在C++中extern还有另外一种作用,用于指示C或者C++函数的调用规范。如在C++中调用C库函数,就需要在C++程序中用extern “C”声明要引用的函数。这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。主要原因是C++和C程序编译完成后在目标代码中命名规则不同,用此来解决名字匹配的问题。


12.

一个可执行程序包括BSS段、数据段、代码段(文本段):

BSS(Block by Start Symbol) :通常指用来存放程序中未初化的全局变量和静态变量的一块内存区域。BSS段属于静态内存分配。

特点是:可读写的,在程序执行之前BSS段为自动清零,所以未初始的全局变量在程序执行之前已经成零了。

数据段:通常用来存放程序中已初始化的全局变量和静态变量的一块内存区域。

DATAsegment 属于静态内存分配。

代码段:通常是指用来存放程序代码的一块内存区域,这部分区域的大小在程序运行前就已确定,并且内存区域通常属于只读,某些架构允许代码段可写,即可以修改,在代码段中,也有可能包含一些只读的常数变量,例如字符串变量等。

堆(heap:用于存放程序中被动态分配的内存段,大小不固定,可动态扩大或缩减, malloc /free

栈(stack):用来存放程序临时创建的局部变量,但不包括static声明的变量。除此之外,在函数被调用时,其参数也会被压入发起调用的堆栈中,并且待到调用结束后,函数的返回值也会被放会栈中,由于栈的先进后出的特点,所以栈特别方便用来保存/恢复调用现场,从这个意义来讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。

bss段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小。data段(已手动初始化的数据)段则为数据分配空间,数据保存在目标文件中。数据段包含经过初始化全局变量以及它们的值。BSS段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段的后面。当这个内存区进入程序的地址空间后全部清零。


0 0
原创粉丝点击