今天老師講的一道題,陣列實作約瑟夫問題。
我還是沒有明白怎么理解把陣列名a傳遞給int b[ ]
uj5u.com熱心網友回復:
實參傳的是a的地址,形參可以隨便寫的,a[], b[]都可以uj5u.com熱心網友回復:
編譯器實際上是用指標來代替陣列名字的引數的陣列名a,本身就代表一個地址(陣列的首地址),可以當指標變數賦值給別人,(這就是所謂的右值)
但是你不能給他賦值
比如
int a[10];
int *p;
a = p; //錯誤,a是陣列名,不能再給他賦值了
p = a;//ok,讓指標p指向陣列a的首地址,
//你可以這樣理解,編譯器看到這樣的賦值,即陣列名字當右值(在等號右邊), 執行固定的動作,把這個a轉化為地址,然后賦值給p
而void ysf(int b[], int n1, int m1);雖然語法上是這么寫,
這里你肯定會有疑問,既然上面的例子,陣列名字都不能當作值 比如a=p,是錯誤的,這里不就是b =a嗎,不也一樣是不行的?
這個邏輯沒錯,所以,實際上編譯器把他轉化成 void ysf(int *b, int n1, int m1)這樣的形式的
至于語言上,可以寫成void ysf(int b[], int n1, int m1);這樣,只是名面上更好的暗示別人,這里最好是傳入一個連續的記憶體地址
就是說,我可能會在函式里操作 *(b + 1); , *(b+2), 試圖在暗示呼叫者:“呼叫者, 你別傳個單獨的地址進來,那樣可能越界哦“
你要好好體會陣列名 和指標變數的區別
int a[10];a只是編譯時候的一個標簽,a 你可以認為是虛的,只在編譯時存在
而指標變數
int *p; 他是一個指標變數,運行的時候,有一塊記憶體用于存放這個變數的值
和其他任意變數,例如int i = 1;你都可以把變數想象成,記憶體中對應的一個格子,
干脆想象成一個盒子得了;
CPU對記憶體的地址不外乎兩種操作,讀和寫,還有其他嗎? 沒了
1. 對于寫
int i = 1;//i 就是一個專門存放整型的盒子,你可以給他放1,也可以放2
int j = 100;// ~·······和上面類似
int *p = &i; //p 是一個專門放指標(地址)的盒子, 這里是給他放i的地址,你也可以把j的地址放進去
p = &j; 這樣變的只是盒子p,現在他不放 i 的地址了,變成放 j 的地址了
2 對于讀
printf("%d\n", i);
把盒子i 的內容取出來, 交給終端顯示
對機器來說,往盒子(記憶體)里寫,或者從中讀,都是用地址來操作的,變數只是程式語言(比如你現在用的C語言提供的抽象)
編譯器會把他轉化為地址,總的來說一一切都是地址。。
------
然而 int a[10]; 呢, 他代表的是10個連續的盒子,跟 int i; 相比,他只是個大點的盒子罷了
也許你想用上面的例子去套,但是一次放幾個好呢,假如可以的話,a = 1, a=2 3 4,??這樣的操作到底放到哪里去好呢
沒法弄,太多可能了,有歧義
所以 用這種方式 a[0] 代表第一個格子, a[1]代表第二個 這樣就沒歧義了,按索引來操作
個人覺得你可以想象成他相當于定義了 int a0, a1, a2,,,,a9; 10個整型變數,且這10個變數的空間是連續的
省去了你定義10次的麻煩,而名字a的職責在這里就變了,只代表首地址,在程式運行的時候,a其實是虛無的,
你可以認為他消失了,沒有他自己的盒子(記憶體),a[0]到a[9]都要存正經資料,可以理解成他只是純編譯時的中間工具。
可能越扯越遠了,看哪些對你有啟發,拿去用吧
uj5u.com熱心網友回復:
我感覺受益匪淺,謝謝
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/104398.html
標籤:C語言
上一篇:求助!C++char*不存在?
