我正在查看代碼作為我目前正在從事的專案的參考。我注意到,不是有一個變數,然后只是臨時轉換一個指向它的指標以將其作為引數傳遞,而是將它設定為始終為指標型別。(它說的那一行Sprite* createSprite
)
Sprite* createSprite(Sprite* model, int x, int y) {
Sprite* self = malloc(sizeof(Sprite));
initSprite(model, self, x, y);
return self;
}
我假設這樣做是使變數永久成為指標。
而不是只在需要時使用指標:
int a;
someFunction(&a); // We can still use a, and we can also pass it to someFunction as a pointer
此代碼將 sprite 物件永久轉換為指標:
int *a;
someFunction(a); // While we can still use a, it will never be a normal variable.
人們為什么要這樣做,這樣做有什么好處?
uj5u.com熱心網友回復:
假設您的程式中需要幾個精靈。你可以做類似的事情
Sprite s1;
initSprite(model, &s1, x, y);
Sprite s2;
initSprite(model, &s2, x, y);
Sprite s3;
initSprite(model, &s3, x, y);
稍后,如果你需要更多,你可以用同樣的方式來做:
Sprite s4;
initSprite(model, &s4, x, y);
Sprite s5;
initSprite(model, &s5, x, y);
但是,遲早這會變得乏味且不可行,因此您需要動態記憶體分配。這就是createSprite
函式正在做的事情。其中的關鍵是那個電話
Sprite* self = malloc(sizeof(Sprite));
它為另外一個精靈動態分配記憶體。這樣,您的程式可以在其中包含任意數量的精靈,很可能是一個直到運行時才知道的數字,一旦用戶開始做某事。但是動態分配的記憶體總是最終涉及指標。它不能使用像 yourint a
或 my這樣的靜態變數名稱Sprite s1
,因為根據定義,這些變數只能有一個固定的靜態數字(即,您在撰寫程式的那天選擇的數字)。
為了比較,看看createSprite
函式的其他三種撰寫方式可能是有啟發性的,而不使用動態記憶體分配。
Sprite* createSprite2(Sprite* model, int x, int y) {
Sprite self;
initSprite(model, &self, x, y);
return &self;
}
這會創建一個型別的區域變數Sprite
(不是指向- 的指標Sprite
),但它根本不起作用。該區域變數在createSprite2
回傳時消失,因此指向它的指標立即無效。
Sprite* createSprite3(Sprite* model, int x, int y) {
static Sprite self;
initSprite(model, &self, x, y);
return &self;
}
這里我們制作了區域Sprint
變數static
,所以它不會在createSprite3
回傳時消失。但這也不起作用,因為現在實際上只有一個Sprite
物件,由曾經呼叫過的所有呼叫者共享createSprite3
,這幾乎可以肯定不是想要的,也不會起作用。
但是還有另一種可能性,它實際上會起作用:
Sprite createSprite4(Sprite* model, int x, int y) {
Sprite self;
initSprite(model, &self, x, y);
return self;
}
請注意,這createSprite4
并不回傳一個指標——它回傳一個實際的Sprite
. 所以來電者可能看起來像
Sprite s1 = createSprite4(model, x, y);
或者
Sprite manysprites[10];
for(int i = 0; i < 10; i )
manysprites[i] = createSprite4(model, x, y);
正如我所說,這可以正常作業,并且有點反駁我的斷言“動態分配的記憶體總是最終涉及指標”。(但從技術上講,這里仍然沒有動態分配的記憶體,正如我們從源代碼中看到的那樣,恰好分配了 1 或 10 個 Sprite。)
uj5u.com熱心網友回復:
在你的第一個例子中
int a;
someFunction(&a);
'a' 存在于堆疊中,因此它有一個您可以使用并獲取地址等的名稱。
精靈示例
Sprite* createSprite(Sprite* model, int x, int y) {
Sprite* self = malloc(sizeof(Sprite));
initSprite(model, self, x, y);
return self;
}
幾乎可以肯定是在堆上動態分配其資料。您可以參考動態分配的記憶體的唯一方法是通過指標
uj5u.com熱心網友回復:
createSprite
回傳一個指向self
; 如果是這樣(我猜你也希望這樣):
Sprite* createSprite(Sprite* model, int x, int y) {
Sprite self;
initSprite(model, &self, x, y);
return &self;
}
在函式執行結束時分配的記憶體self
將無效;嘗試通過回傳的指標訪問它很可能會導致段錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/478553.html