Re: [問題] 關於記憶體位置和記億體位置之值
※ 引述《g56 (GG5566)》之銘言:
: 遇到的問題: (題意請描述清楚)
: 各位大大好
: char string[]="Input an integer";
: int p1=(int) &string;
: // p1設定成為string的記憶體所在位置的值
: printf("%s\n",p1);
: // ^^這樣寫同樣可以印出字串string
: --------------------------
: 以上為程式碼,
: 但小弟我一直無法接收p1印出來為字串,
: 因為這行 int p1=(int) &string; 的意思是把string的記憶體位置值傳給p1
: 所以p1應該是為記億體位置而不是字串..
: 謝謝您看完這個問題...<(_ _)>
: 希望得到的正確結果:
: p1為記憶體位置
: 開發平台: (例: VC++ or gcc/g++ or Dev-C++, Windows or Linux)
: windows
: 有問題的code: (請善用置底文標色功能)
: p1=(int) &string;
: 不是記憶體位置
char string[] = "input an integer";
這行的意思是定義一個 char array,string 是 identifier。
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│ i│ n│ p│ u│ t│ │ a│ n│ │ i│ n│ t│ e│ g│ e│ r│\0│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
↖
這是一個記憶體的位置,假設是 00000000,所以後面可以類推,如下圖
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│ i│ n│ p│ u│ t│ │ a│ n│ │ i│ n│ t│ e│ g│ e│ r│\0│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
↖ ↖ ↖ ↖
╲ ╲ ╲ 00000003
╲ ╲ 00000002
╲ 00000001
00000000
然後 00000000 這個 value 放在一個叫做 string 的變數裡面。
┌────┐
│00000000│
└────┘
string
我們一個一個看 int p1=(int) &string;
&string 拿到 00000000
(int) 把 00000000 這個 value 的 type 從 address 轉換成一個 int,
所以 p1 的 value 會變成 00000000。
然後 printf("%s\n",p1);
p1 是一個 int,而 %s 要求的是一個 pointer,型別不合。
所以你要改成 (char *) p1,這樣會變成一個 address 也就是 00000000
所以最後 printf("%s\n", (char *) p1); 會得到你要的結果。
不過與其這樣,你不如寫:
char string[] = "Input an integer";
char *pointer = string;
printf("%s\n", pointer);
啊只是你這樣 pointer 跟 string 這兩個 identifier 的 value
都是同一個 address 就是了,這又叫做 shallow copy,或淺 copy。
因為你透過 string 這個 identifier 做的任何事情,
透過 pointer 也會發現一樣的改變。
如果要真正產生兩個獨立的個體,你需要給 pointer 一個位置,最簡單的方法如下。
char string = "Input an integer";
char array[30];
char *pointer = array;
int counter;
for (counter = 0; counter < 17; counter++)
*(pointer + counter) = string[counter];
像這樣透過 for loop 慢慢一個一個 copy,才可以確實做出兩個獨立的個體。
相對於 shallow copy,這叫做 deep copy。
那 counter < 17 這裡的條件式其實可以寫成 counter < strlen(string) + 1
strlen 這個 function 放在 string.h 這個 header file 裡面。
然後 + 1 是要連 string 結尾的 \0 一起算進去。
不過這樣等於每次做 forloop 的時候都要執行一次 strlen(),考慮到效能,
最好宣告一個 int limit = strlen(string);
然後改寫成 counter < limit 比較有效能。
然後我們這裡配置記憶體給 pointer 的方式是由程式設計師靜態宣告一個 arry。
這樣很不方便,其實我們可以改成用 malloc 這個函式動態宣告,我們可以這樣寫。
malloc(limit) 這樣寫是可以的,只是習慣不太好。
為什麼這樣說呢?因為在這裡因為是 char 的關係,所以只有 1 byte,剛好沒問題。
如果是 int 以 32 bit compiler 來說 int 是 4 個 byte,所以就是要 limit * 4。
那這樣寫還是不太好,因為有的 compiler 的 int 只有 16 bits,就是 limit * 2,
那到底要寫 4 還是 2?很簡單我們只要寫 limit * sizeof (int) 就會幫我們抓。
sizeof (int) 會依據系統的關係,抓到 (int) 所需要的大小。
所以我們寫 malloc( limit * sizeof (int) ) 啊不過 malloc 傳回來的 data type
是 void *,而我們宣告的 pointer type 是 char *,所以要做 type casting。
(char *) malloc ( limit * sizeof (int) )
結果就是 char *pointer = (char *) malloc ( limit * sizeof (int) );
所以我們最後這樣寫。
#include <string.h>
int main(void)
{
char string[] = "Input an array";
int limit = strlen(string) + 1;
char *pointer = (char *) malloc( limit * sizeof (int) );
int counter;
for (counter = 0; counter < limit; counter++)
*(pointer + counter) = string[counter];
return 0;
}
啊不過這裡 *(pointer + counter) 的寫法有點拖泥帶水,可以直接寫成:
pointer[counter]。
也就是改成:
pointer[counter] = string[counter];
啊不過以上 for loop 的部份其實有些好的 function 可以用,叫 strcpy,
也是放在 string.h 這個 header 裡面。
我們可以寫成下面這樣
int main(void)
{
char string[] = "Input an integer";
int limit = strlen(string) + 1;
char *pointer = (char *) malloc( limit * sizeof (int) );
strcpy(pointer, string);
printf("%p = %s; %p = %s\n", string, string, pointer, pointer );
return 0;
}
跑看看就知道了。
--
One should love animals. They are so tasty.
每個人都應該愛動物,他們是如此美味。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 123.204.248.250
推
11/24 21:18, , 1F
11/24 21:18, 1F
推
11/24 21:20, , 2F
11/24 21:20, 2F
→
11/24 21:22, , 3F
11/24 21:22, 3F
※ 編輯: B9 來自: 123.204.248.250 (11/24 21:24)
推
11/24 21:24, , 4F
11/24 21:24, 4F
推
11/24 21:24, , 5F
11/24 21:24, 5F
→
11/24 21:25, , 6F
11/24 21:25, 6F
推
11/24 21:30, , 7F
11/24 21:30, 7F
→
11/24 21:38, , 8F
11/24 21:38, 8F
→
11/24 21:41, , 9F
11/24 21:41, 9F
→
11/24 21:43, , 10F
11/24 21:43, 10F
→
11/25 07:16, , 11F
11/25 07:16, 11F
推
11/25 14:38, , 12F
11/25 14:38, 12F
→
11/25 14:38, , 13F
11/25 14:38, 13F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章