![](/img/trans.png)
[英]In C, why can't the value of a pointer-to-char variable be changed after it has been assigned?
[英]In C, why can't an integer value be assigned to an int* the same way a string value can be assigned to a char*?
我一直在瀏覽網站,但尚未找到答案。
用一個例子來解釋這個問題是最容易的(至少對我來說)。
我不明白為什么這是有效的:
#include <stdio.h>
int main(int argc, char* argv[])
{
char *mystr = "hello";
}
但是這會產生一個編譯器警告(“初始化使整數從沒有強制轉換的整數中生成”):
#include <stdio.h>
int main(int argc, char* argv[])
{
int *myint = 5;
}
我對第一個程序的理解是創建一個名為mystr的變量,類型為pointer-to-char,其值是字符串文字“hello”的第一個字符('h')的地址。 換句話說,使用此初始化,您不僅可以獲取指針,還可以定義指針指向的對象(在本例中為“hello”)。
那么,為什么int *myint = 5;
看似沒有實現與此類似的東西,即創建一個名為myint的變量,類型指針指向int,其值是值'5'的地址? 為什么這個初始化既不給我指針也定義指針所指向的對象?
實際上,您可以使用復合文字來實現,這是1999 ISO C標准添加到該語言中的一項功能。
字符串文字的類型為char[N]
,其中N
是字符串的長度加1.與任何數組表達式一樣,它在大多數但不是所有上下文中都隱式轉換為指向數組第一個元素的指針。 所以這:
char *mystr = "hello";
為指針mystr
分配內容為"hello"
的數組的初始元素的地址(后跟終止'\\0'
mystr
字符)。 順便說一句,寫起來更安全:
const char *mystr = "hello";
整數沒有這種隱式轉換 - 但你可以這樣做:
int *ptr = &(int){42};
(int){42}
是復合文字,它創建一個初始化為42
的匿名int
對象; &
獲取該對象的地址。
但要小心:由字符串文字創建的數組始終具有靜態存儲持續時間,但復合文字創建的對象可以具有靜態或自動存儲持續時間,具體取決於它出現的位置。 這意味着如果從函數返回ptr
的值,則指針仍指向它時,具有值42
的對象將不再存在。
至於:
int *myint = 5;
嘗試將值5
分配給int*
類型的對象。 (嚴格來說,這是初始化而不是賦值,但效果是一樣的)。 由於沒有從int
到int*
隱式轉換(除了0
的特殊情況被視為空指針常量),這是無效的。
當你做char* mystr = "foo";
,編譯器將在可執行文件的特殊只讀部分中創建字符串"foo"
,並有效地將語句重寫為char* mystr = address_of_that_string;
對於任何其他類型,包括整數,都沒有實現相同的功能。 int* myint = 5;
將myint
設置為指向地址5
。
我將我的答案分成兩部分:
1,為什么char* str = "hello";
已驗證:
char* str
為指針聲明一個空格(表示當前體系結構上的內存地址的數字)
當你寫"hello"
你實際上用6個字節的數據填充堆棧
(不要忘記空終止)讓我們說地址0x1000 - 0x1005
。
str="hello"
將該5個字節(0x1000)的起始地址分配給*str
所以我們擁有的是:
1. str
,在內存中占用4個字節 ,保存數字0x1000
(僅指向第一個字符!)
2. 6字節 'h''e'''''''''''0'
2,為什么int* ptr = 0x105A4DD9;
無效:
好吧,這不完全正確!
如前所述,指針是一個代表地址的數字,
那么為什么我不能分配這個號碼?
它並不常見,因為大多數情況下您提取數據地址而不是手動輸入地址。
但你可以,如果你需要! ...
因為它不是常見的東西,
編譯器希望確保您在建議中這樣做,而不是錯誤地強制您將數據作為CAST
int* ptr = (int*)0x105A4DD9;
(主要用於內存映射的硬件資源)
希望這清楚的事情。
干杯
“在C中,為什么不能將整數值賦給int *,就像將字符串值賦給char *一樣?”
因為它甚至不是類似的情況,更不用說“同樣的方式”。
字符串文字是一個char
數組,它是一個數組 - 可以隱式轉換為指向其第一個元素的指針。 所述指針是char *
。
但是int
既不是指針本身,也不是數組,也不是任何其他隱式可轉換為指針的東西。 這兩種情況沒有任何共同之處。
問題是您正在嘗試將地址5分配給指針。 在這里你沒有取消引用指針,你將它聲明為指針並將其初始化為值5(作為一個肯定不是你打算做的地址)。 您可以執行以下操作。
#include <stdio.h>
int main(int argc, char* argv[])
{
int *myint, b;
b = 5;
myint = &b;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.