前言:类型定义后,存储在哪里?变量定义后存储在哪里?程序代码存储在哪里?
1. 全局数据区和程序代码区
类型定义后,存在内存的只读区域,不可见,无法取得地址。类变量记录的是地址偏移,与对象绑定才能取得地址。
变量:
全局变量存在全局数据区,全局静态变量存在全局数据区的全局静态变量段。(两者相临或相差几个字节)。
名空间变量存在全局数据区,和全局变量同一存储区域,名空间静态变量存在全局数据区的名空间静态变量段,和全局静态变量同一存储区域。
类变量名称列表中记录的是地址偏移,和对象绑定才能取得地址。类静态变量存在全局数据区的类静态变量段,和全局静态变量不同存储区域。
函数(函数也是变量一种):
全局函数存在程序代码区,全局静态函数存在程序代码区的全局静态函数段。(两者相邻即同一存储区域)。
名空间全局函数存在程序代码区,和全局函数同一存储区域,名空间静态函数存在程序代码区的名空间静态函数段,和全局静态函数同一存储区域。
类函数存在程序代码区,和全局函数不同存储区域,类静态函数存在程序代码去的类静态函数段,和全局静态函数不同存储区域。
先看如下程序:
#include <iostream>
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
typedef void (*FUNC)();
const int X = 1;
int x;
int *p;
void (*func_a)();
void func_b(){};
class C1
{
public:
typedef int INT;
typedef void (*FUNC)();
public:
int i;
int j;
INT k;
static int m;
static int n;
public:
void FuncA() {};
void FuncB() {};
static void FuncC() {};
static void FuncD() {};
static void FuncE() {};
FUNC FuncF;
void (*FuncG)();
//int C1::*FuncH();
void Test() {
FuncF = FuncE;
FuncG = FuncE;
printf("void FuncA 地址:%p\n", &C1::FuncB);
printf("void FuncA 地址:%p\n", &C1::FuncC);
printf("void FuncA 地址:%p\n", FuncC);
}
};
const int Y = 2;
int y;
void func_c(){};
C1::FUNC func_d = func_c;
int C1::m = 1;
int C1::n = 2;
class C2
{
public:
int i;
int j;
int k;
static int m;
static int n;
public:
void FuncA() {};
void FuncB() {};
static void FuncC() {};
static void FuncD() {int i = 0; int j = 0; };
static void FuncE() {};
};
int C2::m = 1;
int C2::n = 2;
namespace n1
{
int i;
int j;
static int m = 0;
static int n = 0;
void FuncA() {};
void FuncB() {};
static void FuncC() {};
static void FuncD() {};
}
int main()
{
printf("class C1 长度:%d\n", sizeof(C1));
printf("const int X 地址:%p\n", &X);
printf("int x 地址:%p\n", &x);
printf("int *p 地址:%p\n", &p);
printf("void (*func_a)() 地址:%p\n", &func_a);
printf("void func_b(){} 地址:%p\n", &func_b);
printf("const int Y 地址:%p\n", &Y);
printf("int y 地址:%p\n", &y);
printf("void func_c(){} 地址:%p\n", &func_c);
printf("C1::FUNC func_d = func_c 地址:%p\n", &func_d);
printf("C1 int i 地址:%p\n", &C1::i);
printf("C1 int j 地址:%p\n", &C1::j);
printf("C1 int k 地址:%p\n", &C1::k);
printf("C1 static int m 地址:%p\n", &C1::m);
printf("C1 static int n 地址:%p\n", &C1::n);
printf("C1 void FuncA() {} 地址:%p\n", &C1::FuncA);
printf("C1 void FuncB() {} 地址:%p\n", &C1::FuncB);
printf("C1 static void FuncC() {} 地址:%p\n", &C1::FuncC);
printf("C1 static void FuncD() {} 地址:%p\n", &C1::FuncD);
printf("C1 static void FuncE() {} 地址:%p\n", &C1::FuncE);
printf("C1 FUNC FuncF 地址:%p\n", &C1::FuncF);
printf("C1 void (*FuncG)() 地址:%p\n", &C1::FuncG);
printf("C2 int i 地址:%p\n", &C2::i);
printf("C2 int j 地址:%p\n", &C2::j);
printf("C2 int k 地址:%p\n", &C2::k);
printf("C2 static int m 地址:%p\n", &C2::m);
printf("C2 static int n 地址:%p\n", &C2::n);
printf("C2 static void FuncC() {} 地址:%p\n", &C2::FuncC);
printf("C2 static void FuncD() {} 地址:%p\n", &C2::FuncD);
printf("C2 static void FuncE() {} 地址:%p\n", &C2::FuncE);
printf("n1 int i 地址:%p\n", &n1::i);
printf("n1 int j 地址:%p\n", &n1::j);
printf("n1 static int m 地址:%p\n", &n1::m);
printf("n1 static int n 地址:%p\n", &n1::n);
printf("n1 void FuncA() {} 地址:%p\n", &n1::FuncA);
printf("n1 void FuncB() {} 地址:%p\n", &n1::FuncB);
printf("n1 static void FuncC() {} 地址:%p\n", &n1::FuncC);
printf("n1 static void FuncD() {} 地址:%p\n", &n1::FuncD);
return 0;
}
运行结果:
class C1 长度:32
const int X 地址:0x400fd0 程序代码区(常量段)
int x 地址:0x602060 全局数据区
int *p 地址:0x602068 全局数据区(64位编译环境,指针占块大小为64位)
void (*func_a)() 地址:0x602070 全局数据区
void func_b(){} 地址:0x400674 程序代码区(整个函数定义占48位,不同编译环境所占块大小不同)
const int Y 地址:0x400fd4 程序代码区(常量段)
int y 地址:0x602078 全局数据区
void func_c(){} 地址:0x40067a 程序代码区
C1::FUNC func_d = func_c 地址:0x602038 全局数据区(类内声明的类型定义的变量,与类的static变量相同,存储位置相邻)
C1 int i 地址:(nil) 不可见区域,与类对象帮定,取得的地址为地址偏移
C1 int j 地址:0x4
C1 int k 地址:0x8
C1 static int m 地址:0x602040 全局数据区(类静态变量段)
C1 static int n 地址:0x602044
C1 void FuncA() {} 地址:0x400a26 程序代码区(类函数段)
C1 void FuncB() {} 地址:0x400a30
C1 static void FuncC() {} 地址:0x400a3a 程序代码区(类静态函数段,与类函数同同一存储区域,与全局函数不同存储区域)
C1 static void FuncD() {} 地址:0x400a40
C1 static void FuncE() {} 地址:0x400a46
C1 FUNC FuncF 地址:0x10
C1 void (*FuncG)() 地址:0x18
C2 int i 地址:(nil)
C2 int j 地址:0x4
C2 int k 地址:0x8
C2 static int m 地址:0x602048 全局数据区(类静态变量段,不同类的静态变量在同一存储区域)
C2 static int n 地址:0x60204c
C2 static void FuncC() {} 地址:0x400a4c 程序代码区(类静态函数段)
C2 static void FuncD() {} 地址:0x400a52
C2 static void FuncE() {} 地址:0x400a66
n1 int i 地址:0x60207c 全局数据区(名空间变量段,与全局变量同一存储区域)
n1 int j 地址:0x602080
n1 static int m 地址:0x602088 全局数据取(名空间静态变量段,与全局静态变量同一存储区域,与全局名空间变量、全局变量不同存储区域)
n1 static int n 地址:0x60208c
n1 void FuncA() {} 地址:0x400680 程序代码区(名空间函数段,与全局函数同一存储空间)
n1 void FuncB() {} 地址:0x400686
n1 static void FuncC() {} 地址:0x40068c 程序代码区(名空间静态函数段,与名空间函数段、全局函数段同一存储区域)
n1 static void FuncD() {} 地址:0x400692