iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 7
1

前言提到:


因為不需要用到 **get_a ,所以
function(int **get_a) 可以換成 function(int *get_a)
不影響功能和行為,只是編譯器會給出警告。

反正只是純粹進行地址的儲存,又可不可以再換成
function(void *get_a) 呢? (int* -> void*)

竟然是不行的。 ∑(っ °Д °;)っ、


要知道為什麼,就順便需要了解一下數據、數據類型的本質。

數據類型只是看待數據的一種方式
數據在本質上沒有類型的。

▌數據本質:

本質上數據衹是01010101010二進制這種東西,沒有意義。

數據類型給予了他們意義或者說定義
像定義了數據所佔的字節長度

例如:
sizeof(int) = 4
sizeof(double) = 8;

有趣的是,指標類型所佔的字節長度均是 4 Byte,即:
sizeof(void*) = 4;
sizeof(int*) = 4;
sizeof(long*) = 4;
sizeof(float*) = 4;
sizeof(double*) = 4;
sizeof(結構體*) = 4;
sizeof(void******) = 4;

主要原因是指標類型是用來儲存地址的,
4 個字節 足夠定址所有地址。


在內存上或者二進制這種層面上,
不同指標類型儲存的數據(地址)是沒有分別

其分別只有在最頂層取值層級


▌來個程式看看:

int main(){
    char a = 'a';
	double *double_ptr = &a;
	int *int_ptr = &a;
	printf("%c\n", *double_ptr);
	printf("%c", *int_ptr);
    return 0;
}

輸出:

a
a

%c 就是看待數據的方式
即使數據的地址是用 ( int* ) 還是 ( double* ) 去裝,
取值出來的數據,只要用適當的方式,
還是會讀到正確的數據

所以指標類型儲存的只是很純粹的地址
就只有最後一層取值會用對應自身的數據類型,
去看待數據。


▌說了這麼多,

為啥function(int *get_a)不能再換成
function(void *get_a) 呢?

int *get_a 的最後一層取值會用 int 去看待數據。
void *get_a 呢?

是 沒有變數定義的 void,
我們不能宣告一個 void 類型的變數,
你要編譯器去怎麼看待那些數據??! ∑(っ °Д °;)っ、

看看編譯器怎麼說:

https://ithelp.ithome.com.tw/upload/images/20181022/20111788zePUy73KKg.png
看看 Microsoft 怎麼說:
https://ithelp.ithome.com.tw/upload/images/20181022/20111788BiqOoYdA7w.png
看看 維基百科 怎麼說:
https://ithelp.ithome.com.tw/upload/images/20181022/20111788Be0SpGu1wA.png


指標有太多奇怪的特性,
如有錯誤,請以自行測試的結果為准。


呼~ 好忙,今天就醬。~ (`・ω・´) ~~


參考資料:

C语言1之数据类型的本质
https://blog.csdn.net/wangdapao12138/article/details/79177795

C语言 - 什么是数据类型?数据类型的本质
https://blog.csdn.net/u014622185/article/details/49640281?utm_source=blogxgwz0

编程语言里面“强制转换”在内存上的机理是什么? - 知乎
https://www.zhihu.com/question/20482511

左值和右值運算式
https://msdn.microsoft.com/zh-tw/library/bkbs2cds.aspx

不完全類型 - 維基百科,自由的百科全書
https://zh.wikipedia.org/wiki/%E4%B8%8D%E5%AE%8C%E5%85%A8%E7%B1%BB%E5%9E%8B


上一篇
Days 6: 重溫指標:不使用回傳地址方式的函數(續.)
下一篇
Days 8: 重溫指標:雜項:指標宣告、運算符
系列文
30 Days 如何把 C 語言偽裝成高階語言 OWO /31

尚未有邦友留言

立即登入留言