我有一個簡單的程式,scanf一次一個值,然后將它存盤在一行(p)中,然后將它存盤在一個矩陣(pg)中。
//
// Created by herveDarritchon on 15/01/2022.
//
#include <stdio.h>
int main() {
int dim = 0;
printf("dim ?\n");
scanf("%d", &dim);
short tab[dim];
short *p;
short **pg;
p = &tab[0];
short tab_double[dim][dim];
pg = (short **) &tab_double[0];
for (int j = 0; j < dim; j ) {
for (int i = 0; i < dim; i ) {
printf("value: ");
scanf("%d", &p[i]);
printf("value stored : %d\n", p[i]);
}
printf("value in tab: ");
for (int l = 0; l < dim; l ) {
printf("%d|", tab[l]);
}
printf("\n");
pg[j] = tab;
printf("value ub pg[%d]: ", j);
for (int l = 0; l < dim; l ) {
printf("%d|", pg[j][l]);
}
printf("\n");
}
for (int k = 0; k < dim; k ) {
printf("value ub pg[%d]: ", k);
for (int l = 0; l < dim; l ) {
printf("%d|", pg[k][l]);
}
printf("\n");
}
}
結果是
dim ?
2
value: 1
value stored : 1
value: 2
value stored : 2
value in tab: 1|2|
value ub pg[0]: 1|2|
value: 3
value stored : 3
value: 4
value stored : 4
value in tab: 3|4|
value ub pg[1]: 3|4|
value ub pg[0]: 3|4|
value ub pg[1]: 3|4|
但最后,矩陣 (pg) 僅將最后一行存盤在其所有索引中:(
我想我對指標做錯了......但我不明白為什么矩陣只有最后一行。
uj5u.com熱心網友回復:
線
pg = &tab_double[0];
給你一個編譯器警告。您似乎通過添加型別轉換來抑制此警告:
pg = (short **) &tab_double[0];
但是,像這樣抑制編譯器警告并不是一個好主意。編譯器指出出了點問題。
隨著線
short tab_double[dim][dim];
您正在宣告一個二維 (2D) 陣列。
二維陣列只不過是陣列的陣列。內部陣列是型別short[dim](dim元素陣列,其中每個元素是型別short),外部陣列是型別short[dim][dim](dim元素陣列,其中每個元素是型別short[dim])。
如果要pg指向外部陣列的第一個元素,則應使其型別反映這一點。您希望它指向 type 的元素short[dim]。因此,指標的型別應該是short (*)[dim](括號是必需的,否則該型別將是指向型別物件的指標陣列short)。所以你應該像這樣宣告指標:
short (*pg)[dim];
但是,您改為這樣宣告指標:
short **pg;
這告訴編譯器pg將指向一個指向 a 的指標short。但是,此資訊是不正確的。如上所述,您希望它指向型別的物件(即指向型別元素short[dim]的陣列)。dimshort
陣列不是指標(盡管在某些情況下陣列經常衰減為指標)。
修復此問題后,您的編譯器現在將在以下行中給您一個錯誤:
pg[j] = tab;
這是因為您不能直接為陣列賦值。但是,您可以
- 在回圈中一次將一個元素從一個陣列復制到另一個陣列,直到復制整個陣列,或者
- 使用 . 將一個陣列的記憶體內容復制到另一個陣列
memcpy。
uj5u.com熱心網友回復:
您將陣列與指標混淆,并且似乎假設它們在某種程度上是相同的。那不是真的。
查看記憶體布局:
short arr[dim][dim];
在記憶體中,這看起來像這樣(假設dim==3):
--------- --------- --------- --------- --------- --------- --------- --------- ---------
| 0 | 2 | 4 | 6 | 8 | A | C | E | 10 |
--------- --------- --------- --------- --------- --------- --------- --------- ---------
|arr[0][0]|arr[0][1]|arr[0][2]|arr[1][0]|arr[1][1]|arr[1][2]|arr[2][0]|arr[2][1]|arr[2][2]|
--------- --------- --------- --------- --------- --------- --------- --------- ---------
這類似于您的 short tab_double[dim][dim];
另一邊看這個:
short **pg;
在記憶體中,這看起來像這樣(假設 32 位地址):
---------- ---------- ----------
| 0 | 4 | 8 |
---------- ---------- ----------
| pg[0] | pg[1] | pg[2] |
---------- ---------- ----------
此外,它取決于p[x]所在位置的內容p[x][0]。
如您所見,記憶體布局short **pg與short tab_double[dim][dim]
通過該分配pg = (short **) &tab_double[0];,您可以告訴編譯器將保存陣列前幾個元素的記憶體視為指標陣列。這會導致記憶體損壞。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/412255.html
標籤:
