天天看點

一個程式帶你搞懂局部,結構體中的變量在記憶體中的存放邏輯

變量(局部,結構體中)的實體存放一鍵摸索

首先了解概念
  1. 變量按聲明順序在記憶體中順序存放。不用對齊存放。而在結構體中聲明的變量都是向 size 最大對齊存放。
  2. 普通變量存放在棧中,為連續區域。
  3. 咱使用進階語言(C++)不能直接對記憶體進行操作。
然後看圖
一個程式帶你搞懂局部,結構體中的變量在記憶體中的存放邏輯
  • 源代碼
#include<iostream>
#include<string>

struct MyStruct
{
	int a;
	std::string b;
	char c;
	double d;
	MyStruct(int _a, char _c, double _d) : a(_a), c(_c), d(_d) {}
};

int main() {
	std::cout << "本測試采用 x86 編譯器 (機器字長 32 位) → 處理器一次可提取 32 位資料" <<
		"\n一個位址存放 8 bit,是以 1 Byte 和 1 位址對應" << '\n';
	std::cout << std::endl;
	int a = 1, b = 2, c = 3;
	double d = 1.11;
	std::string str;
	std::cout << "輸出普通變量 a, b, c 的存放位置" << '\n';
	std::cout << "int 類型變量大小為 4 個位元組(32 bit) char 大小為 1 位元組(8 bit)" << '\n';
	std::cout << "int a 的存放位址 " << &a << '\n';
	std::cout << "int b 的存放位址 " << &b << '\n';
	std::cout << "int c 的存放位址 " << &c << '\n';
	std::cout << "double d 的存放位址 " << &d << "\t大小為 " << sizeof(d) << " Byte" << '\n';
	std::cout << "string str 的存放位址 " << &str << "\t大小為 " << sizeof(str) << " Byte" << '\n';
	std::cout << "然而普通聲明的一個 int 變量所間隔位址空間大小為 &a - &b = " <<
		reinterpret_cast<int>(&a) - reinterpret_cast<int>(&b) << " Byte" << '\n';
	std::cout << "是以 int 型變量順序壓棧時會導緻 8 個位址空間空閑(浪費) 其他類型情況不一" <<
		"\n且變量存放順序為從高位址開始存放,不用對齊存放" << '\n';
	std::cout << std::endl;

	MyStruct mystruct(1, 'c', 1.11);
	std::cout << "輸出結構體中 a, b, c, d 的大小" << '\n';
	std::cout << "大小都是用十進表示" << '\n';
	std::cout << "a 的大小 " << sizeof(mystruct.a) << " Byte" << '\n';
	std::cout << "b 的大小 " << sizeof(mystruct.b) << " Byte" << '\n';
	std::cout << "c 的大小 " << sizeof(mystruct.c) << " Byte" << '\n';
	std::cout << "d 的大小 " << sizeof(mystruct.d) << " Byte" << '\n';
	std::cout << std::endl;

	std::cout << "輸出結構體中 a, b, c, d 的位址" << '\n';
	std::cout << "位址都是用十六進制表示" << '\n';
	std::cout << "a 的位址 " << &mystruct.a << '\n';
	std::cout << "b 的位址 " << &mystruct.b << '\n';
	std::cout << "c 的位址 " << &mystruct.c << '\n';
	std::cout << "d 的位址 " << &mystruct.d << '\n';
	std::cout << "結構體中變量存放按聲明順序對齊(向所占空間最大看齊)存放且從低位址開始存放" << '\n';
	std::cout << std::endl;

	std::cout << "輸出結構體的大小" << '\n';
	std::cout << "定義的結構體大小 " << sizeof(MyStruct) << " Byte" << '\n';
	std::cout << "建立的結構體大小 " << sizeof(mystruct) << " Byte" << '\n';
	// 下面一句又學到了 C++ 中的強制類型轉換
	// reinterpret_cast運算符是用來處理無關類型之間的轉換;它會産生一個新的值,這個值會有與原始參數有完全相同的比特位。
	std::cout << "通過計算得出的結構體大小 " << reinterpret_cast<int>(&mystruct.d) - reinterpret_cast<int>(&mystruct.a)
		+ sizeof(mystruct.d) << " Byte" << '\n';

	system("pause");
	return 0;
}
           

繼續閱讀