線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2188
推到 Plurk!
推到 Facebook!

如何改變 二維陣列 的 行數*列數

尚未結案
quickcccc
一般會員


發表:3
回覆:15
積分:3
註冊:2005-08-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-08-10 12:32:07 IP:203.73.xxx.xxx 未訂閱
以下的 例子 借用 char (*ptr)[5]; 來達到 二維 定位 可是 char (*ptr)[5] 在一開始宣告就已固定 行數 = 5 請問: 如何任意改變 成 (*ptr)[10] 或 (*ptr)[20] .... 以便 陣列 列數*行數 可以任意變動 例如 原本 列數*行數 = ptr[20][5] 變成 列數*行數 = ptr[10][10] 或變成 列數*行數 = ptr[5][20] void main(void) { char (*ptr)[5]; ptr = (char *) malloc (100); // 列數*行數 = 20 * 5 ptr[0][0] = 1; ptr[0][1] = 2; ptr[0][2] = 3; ptr[0][3] = 4; ptr[0][4] = 5; ptr[1][0] = 1; ptr[1][1] = 2; ............. ...... } 謝謝!!
powmien
初階會員


發表:27
回覆:80
積分:41
註冊:2004-10-20

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-08-10 15:05:56 IP:60.248.xxx.xxx 未訂閱
先配置ptr為10*20再改為20*10...  BCB console App 執行正常。 只是不知道釋放memory寫的對不對而已^^b
#include 
#include 
#include 
#include     void main(void){
        int maxc=10,maxl=20;
        int i=0;
        char **ptr;
        // create array
        try
        {
              ptr = new char*[maxc];
              for (int i = 0; i < maxc; i  )
                  ptr[i] = new char[maxl];
        }
        catch (std::bad_alloc)
        {
              printf("Allocate Fail...\n");
              return;
        }
        printf("ptr[%d][%d] Allocate success\n",maxc,maxl);
        // free array memory
        for(i=0;i        發表人 - powmien 於 2005/08/10  15:13:16
        
powmien
初階會員


發表:27
回覆:80
積分:41
註冊:2004-10-20

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-08-10 15:08:00 IP:60.248.xxx.xxx 未訂閱
如果你需要保留原本的數值,可以考慮再用個一維array當temp保留數值,改變好大小再存入。
quickcccc
一般會員


發表:3
回覆:15
積分:3
註冊:2005-08-04

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-08-10 16:11:35 IP:203.73.xxx.xxx 未訂閱
您好 這個方法 我知道 (先配置一維的指標陣列 在另外逐一的配置記憶塊) 但是覺得麻煩 不願用它 第二個方法 就是倍乘 -> (row-1)*col last_col 也是麻煩 還容易錯 我只是覺得很奇怪 為何 c 語言 如此笨拙 main() { char a[100][100]; char (*ptr)[100]; ptr = a; printf(" %d \n" ,sizeof(ptr)) // 答案 sizeof(ptr) = 4 } printf(" %d %d\n" , a[97], ptr[97] )) ; printf(" %d %d\n" , a[98], ptr[98] )) ; printf(" %d %d\n" , a[99], ptr[99] )) ; // 答案 a[97] == ptr[97] == 位置 70,000 // 答案 a[98] == ptr[98] == 位置 70,100 // 答案 a[99] == ptr[99] == 位置 70,200 // ptr 只不過是 4 byte 的變數並不是陣列 卻知道 第列 97,98,99 的 起始記憶體 位置 // 何也 ? 系統 會自己去用倍乘方式 算出 // 也就是 系統 "記錄了資訊" 每一 100 byte 要跳一列 // 既然是 "記錄了資訊" 為何不能再次變動呢 因為我們又不是改變它的size // 例如 int a[100] 改成 int a[100] -> 錯誤 因為 size 不能改變 int a[100] 改成 char a[400] -> size沒變 只是告訴系統 改變讀 寫的 byte // 例如 int (*ptr)[10] 改成 int (*ptr)[5] -> size 沒變 只是告訴系統 倍乘的數字 由 10 變成 5 // 我覺得笨拙原因在此 我不會 組合語言 但我想不透為何無法辦到
quickcccc
一般會員


發表:3
回覆:15
積分:3
註冊:2005-08-04

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-08-10 16:21:04 IP:203.73.xxx.xxx 未訂閱
抱歉嚕 寫錯一地方--- int a[100] 改成 int a[100] 更正成 int a[100] 改成 int a[1000] 正確如下 /////////////////////////////////////////////////// 例如 int a[100] 改成 int a[1000] -> 錯誤 因為 size 不能改變 int a[100] 改成 char a[400] -> size沒變 只是告訴系統 改變讀 寫的方式變成 1 個 byte 而不是 4 個 byte ///////////////////////////////////////////////////
powmien
初階會員


發表:27
回覆:80
積分:41
註冊:2004-10-20

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-08-10 18:32:26 IP:60.248.xxx.xxx 未訂閱
如果你是要探討為何不能任意更動array大小的話@@ 那你可能要問c/c 的作者... 說c/c 笨拙這我不太認同,我的解譯是語法較為嚴謹。 我是先學basic再學assembly再學c/c 的.. 剛碰c/c 也覺得很麻煩,到處都要宣告什麼的, 但是寫久了發現宣告的好,自已真的比較不容易忘記這是什麼東西、 為什麼要這樣宣告的。 c/c 的array在memory 的配置很多書上都有圖講解,本來想畫一張 給您看,後來想想還是別丟人現眼了。 char *ptr; <== ptr 存放的是*ptr這變數的值在memory的address char **ptr; <== ptr 存放的是 *ptr這變數的值在memory的address *ptr存放的是 **ptr這變數的值在memory的address 為什麼 (*ptr)[10] 、 (*ptr)[5] 會計算出位置回傳正確的值回來, 這也是C/C 語法所規範的,為什麼我不去質疑「為什麼它要這樣設計/做」, 我想我的能力還不足去質疑它。 本來還有想多想說的,但是我覺得您的問題範圍或許已經超出我的知識範 圍,還是請真正的高手幫您解答。
powmien
初階會員


發表:27
回覆:80
積分:41
註冊:2004-10-20

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-08-10 18:38:35 IP:60.248.xxx.xxx 未訂閱
引言: 這個方法 我知道 (先配置一維的指標陣列 在另外逐一的配置記憶塊) 但是覺得麻煩 不願用它 第二個方法 就是倍乘 -> (row-1)*col last_col 也是麻煩 還容易錯
就是為了節省重覆開發相似程式的時間… 所以才有function 、巨集 或 sub這種東西的存在。如果是今天叫我選擇要不要使用某一種演算法,我的考量會是效能的高低跟能不能給我正確的結果,而不是麻煩不麻煩^^b...
quickcccc
一般會員


發表:3
回覆:15
積分:3
註冊:2005-08-04

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-08-10 19:28:33 IP:203.67.xxx.xxx 未訂閱
引言: 如果你是要探討為何不能任意更動array大小的話@@ 那你可能要問c/c 的作者... 說c/c 笨拙這我不太認同,我的解譯是語法較為嚴謹。 我是先學basic再學assembly再學c/c 的.. 剛碰c/c 也覺得很麻煩,到處都要宣告什麼的, 但是寫久了發現宣告的好,自已真的比較不容易忘記這是什麼東西、 為什麼要這樣宣告的。 c/c 的array在memory 的配置很多書上都有圖講解,本來想畫一張 給您看,後來想想還是別丟人現眼了。 char *ptr; <== ptr 存放的是*ptr這變數的值在memory的address char **ptr; <== ptr 存放的是 *ptr這變數的值在memory的address *ptr存放的是 **ptr這變數的值在memory的address 為什麼 (*ptr)[10] 、 (*ptr)[5] 會計算出位置回傳正確的值回來, 這也是C/C 語法所規範的,為什麼我不去質疑「為什麼它要這樣設計/做」, 我想我的能力還不足去質疑它。 本來還有想多想說的,但是我覺得您的問題範圍或許已經超出我的知識範 圍,還是請真正的高手幫您解答。
我也是從 Basic 學起 我並不是要問 "array 的 size" 為何無法改變 int a2[10000]; int a1[10000]; int a0[10000]; 編譯時就已經一一"堆入", 所以靜態配置的 size 無法再改變 我是可以理解的 我只是在-----幻想--------以下的想法 char a[10000]; // 先配置一塊固定size char (*ptr)[10]; // 我幻想 這個 10 要是可以變動 該有多好 // 幻想有一個 指令如下 change_array_bound(ptr,20); 如此一來 ptr 將不再以 行數=10 為單位 取而代之 的是 以 行數=20 為單位 這個過程 "並沒有" 改變 char a[10000] 的大小 "也沒改變" sizeof(ptr) 的值 純粹 只是告訴 系統 改變 讀寫 "方式" 而非改變 "大小" 其實在提出問題"前" 我用以下作實驗 (borland c 5.0) int (*ptr)[20]; ptr =(int *)malloc(sizeof(int)*1000); 結果 編譯成功 可是事後 卻編譯失敗 同樣程式碼 卻出現"不同"結果 (看來編譯器還真難寫) 我用 16 位元的 Turbo C 3.0 編譯 , 編譯器 准許 這種寫法 (只是會發出 警告訊息) 執行 也正確 我猜 為何 32 位元 不准許這種寫法 ~~~~~ 因為 為了 安全 其他 還像 int ptr[100]; char *char_1; char_1 = ptr ; // 改成以 1 個 byte 為單位 這種寫法 16 位元 ok ! 32 位元不准許 其實 方法是可以的 只是為了安全而已 (我猜應該是因為 32 位元時代 程式碼越來越龐大 容易造成的 bug 寫法 都被禁止 聽說 Java 的記憶體 是自動管理的 沒有指標 為的就是安全 ) 最後 多謝您先前的回答 ~~ 安安
powmien
初階會員


發表:27
回覆:80
積分:41
註冊:2004-10-20

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-08-11 01:46:56 IP:59.112.xxx.xxx 未訂閱
引言: 純粹 只是告訴 系統 改變 讀寫 "方式" 而非改變 "大小"
我的功力有限,先讓我確認我是不是了解您的需求了?是不是今天您要把 int a[100] 當成 char a[400]來用呢? 事實上不管將資料宣告成何種型態,放進memory 之後想要怎麼來「看」 就是programer自已的事了。 拿 0x63626160 來說.. int 它就等於 0x63626160 因為是4 Byte,但是 當成 char 來看的話 char 為1 Byte ,所以char 只能看到 0x63 0x62 0x61 0x60 ... etc. 請參考小弟的範例… 小弟將 int ptr[5][10] 視為 int ptr[5][10*4] 當然size不變... 只是把int 切成4 char 回傳出來而已… 環境BCB 6 SP4 / VC6 Console Application Compiler success
#include 
#include 
#include 
#include     char MyArray(int v ,int c);
//global
int **ptr;
void main(void){
        int maxc=5,maxl=10;
        int i=0,j=0;
        // create array            try
        {
              ptr = new int*[maxc];
              for (int i = 0; i < maxc; i  )
                  ptr[i] = new int[maxl];
        }
        catch (std::bad_alloc)
        {
              printf("Allocate Fail...\n");
              return;
        }
        printf("ptr[%d][%d] Allocate success!\n",maxc,maxl);
    
        // 給int **ptr 初始值準備做測試
        for(i=0;i>8);
           break;
        case 2:
           temp= ((ptr[vv][c]&0xff0000)>>16);
           break;
        case 3:
           temp= ((ptr[vv][c]&0xff000000)>>24);
           break;
        default:
           temp= (ptr[vv][c]&0xff);
           break;
        }
        return (char)temp;
}
發表人 - powmien 於 2005/08/11 02:12:10
quickcccc
一般會員


發表:3
回覆:15
積分:3
註冊:2005-08-04

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-08-11 09:30:16 IP:61.59.xxx.xxx 未訂閱
真抱歉 我的舉例,我的目的 傳遞不好 讓您浪費不少時間 其實是我沒功力 才會這麼多奇怪問題 把 int a[100] 當成 char a[400] 來看 對於超過 255 的數值 把它切割 好像沒什意義 只是舉例而已 void clear_buffer(char *ptr ,int length) { for(w=0; w<=length-1; w ) { ptr[w]=0; } } main() ( int a[100]; struct tm t; memset(a,1,sizeof[a]) ; // a 雖是 int* 但傳入 memset 後 就是以 char* 型態處理 // 出來後 a[0] 可不是 0001 而是 1111 clear_buffer(a,sizeof[a]); // Borland C 5.0 已不准 int* 轉成 char* clear_buffer(&t,sizeof[t]); // int* 只能對應到相等的 int* // 可是 memset 是可以的 ) 不過 只是覺得 int (*ptr)[10] 中途 可以把 10 改變 成其他 值 應該 會很實用 /////////////////////////// char (*ptr2)[10]; ptr2 = (char *)malloc(100); borland C 5.0 編譯也是 時而可行 時而不行(can not convert (char *)to (char *)[10] ) 我也只好不用這種方法了 /////////////////////////// c 好早好早就有了 而且幾乎都用 c 等到發現它有些不方便之處 有心想改變 它 可能也不容易 因為大變動 可能讓以前 的程式碼 不能相容 void _routine(int x,int y) { int aa[x][y]; } 等到讀到 x,y 值 才決定 "堆疊" 大小 難道辦不到嗎 ? 一定辦得到的 應該是 如你所說的 c 規範 或 某些顧慮 或 速度考量 ....
powmien
初階會員


發表:27
回覆:80
積分:41
註冊:2004-10-20

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-08-11 09:55:36 IP:60.248.xxx.xxx 未訂閱
引言: 真抱歉 我的舉例,我的目的 傳遞不好 讓您浪費不少時間 其實是我沒功力 才會這麼多奇怪問題 把 int a[100] 當成 char a[400] 來看 對於超過 255 的數值 把它切割 好像沒什意義 只是舉例而已 void clear_buffer(char *ptr ,int length) { for(w=0; w<=length-1; w ) { ptr[w]=0; } } main() ( int a[100]; struct tm t; memset(a,1,sizeof[a]) ; // a 雖是 int* 但傳入 memset 後 就是以 char* 型態處理 // 出來後 a[0] 可不是 0001 而是 1111 clear_buffer(a,sizeof[a]); // Borland C 5.0 已不准 int* 轉成 char* clear_buffer(&t,sizeof[t]); // int* 只能對應到相等的 int* // 可是 memset 是可以的 ) 不過 只是覺得 int (*ptr)[10] 中途 可以把 10 改變 成其他 值 應該 會很實用 /////////////////////////// char (*ptr2)[10]; ptr2 = (char *)malloc(100); borland C 5.0 編譯也是 時而可行 時而不行(can not convert (char *)to (char *)[10] ) 我也只好不用這種方法了 /////////////////////////// c 好早好早就有了 而且幾乎都用 c 等到發現它有些不方便之處 有心想改變 它 可能也不容易 因為大變動 可能讓以前 的程式碼 不能相容 void _routine(int x,int y) { int aa[x][y]; } 等到讀到 x,y 值 才決定 "堆疊" 大小 難道辦不到嗎 ? 一定辦得到的 應該是 如你所說的 c 規範 或 某些顧慮 或 速度考量 ....
我只是舉例不管數值如何,陣列如何定義,使用者是您或programer 本身,規範是死的,程式是活的,想達到何種目地只要您功力夠 都是可以完成的,可惜我功力尚淺。 而且很少有程式碼轉換新環境是可以完全不用改寫的,除非類似 java跨在 vm 上面的語言,function都是人寫出來的,不論是memset 或是new、delete..etc. 我認為您在考慮這個某種寫法不能針對 各家compiler跑出正確的結果的同時,不如看看h檔了解別人是怎 麼做的… 也可以去看compiler完之後變assembly 或machine code 了解「根本」是如何實現的,自已寫一個比較通用的版本。 版上也有許多高手改寫delphi、bcb..etc. 的vcl之類的 object .. 或是繼承之後讓obejct 變靈活、好用了,但是都是需 要一定的功力, 程式實不實用是看你有沒有「這個需求」,0-255不就是asc碼? 會無用? 假設今天你在寫flash memory很小的chip... 連int的變數都不能放幾 個.. 那你有10多個開關要判斷要怎麼做?很簡單.. 一個int 當 32個開關用...因為有32 bit.. 做法就雷同我傳char出來的做法 只是做bit 運算,的確! 是很簡單,無義意的運算,但是不這樣做 就無法有效利用chip的有限資源… C/C 不是只能寫Pc app而已… 今天是你對array有疑問我才寫出這樣沒意義的程式,可惜我功力太低 真是很抱歉,或許您可以自行改寫GCC之 open source 之類的 lib 或 是幫vc/bcb寫出您需要的東西再來造福人群也行,在此先感謝將來您對programer的貢獻。 發表人 - powmien 於 2005/08/11 10:05:38
powmien
初階會員


發表:27
回覆:80
積分:41
註冊:2004-10-20

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-08-11 10:21:05 IP:60.248.xxx.xxx 未訂閱
像最近我用iar 寫某chip ...    if(65534+10000>65535) ; <== 這判斷在compiler 裡面永遠不為真.. 因為他的數一超過65535就會回到0做計算,不論你宣告int 、double、long..etc.   所以就要改成 if(65535-10000<65534) 那你會不會認為 宣告成int 、double 、 long 是無義意的? 如果是這樣的話… 你這個project永遠也完成不了… 因為還是有某些運算需要不同的資料型態去完成。 還有 for(i=0;i<=65535;i ){} 這樣的for-loop 就會讓程式crack, 為什麼?因為compiler把code 變成assembly語言判斷時會先讓65535 i 就overflow 了... 所以當初我的主管問我為什麼 for-loop 有bug.. 我卻跟他說我沒遇到問題.. 因為我都用 for(i=0;i<65535;i ){} 出來迴圈之後i==65535再做最後一個 運算... 就是這一個無義意的舉動讓我沒bug... 因為我看過compiler 出來的 assembly... 我了解… 很抱歉我舉了很多完全不相關的答案與問題,文章也有些衝動的感覺,我沒把您 的問題完全了解才是我的疏失,這個問題我不敢再造次了,感謝您讓我學習/受 益良多,謝謝。
quickcccc
一般會員


發表:3
回覆:15
積分:3
註冊:2005-08-04

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-08-11 10:34:07 IP:61.59.xxx.xxx 未訂閱
引言: 把 int a[100] 當成 char a[400] 來看 對於超過 255 的數值 把它切割 好像沒什意義 只是舉例而已 .......... .......... 今天是你對array有疑問我才寫出這樣"沒意義"的程式 ,可惜我功力太低
看來我果然 不善言詞 所以造成不少誤會 ============================================== 假設今天你在寫flash memory很小的chip... 連int的變數都不能放幾 個.. 那你有10多個開關要判斷要怎麼做?很簡單.. 一個int 當 32個開關用... ============================================== 以前 Dos 記憶體 很少 不敷使用 為此 我是把它切成 4 bit 來用 因為我會用到的數值 都在 15 之下 ~~~~看來我我的確是 不善言詞 所以又造成誤會~~~ 然後 再去學學
quickcccc
一般會員


發表:3
回覆:15
積分:3
註冊:2005-08-04

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-08-11 10:51:18 IP:61.59.xxx.xxx 未訂閱
請你別動氣喔 純粹是我表達不好 下次我會知道要如何發問 才....不會造成誤會 抹煞了回覆者熱忱 ~~
arisaka_matsuri
高階會員


發表:25
回覆:205
積分:231
註冊:2003-10-19

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-08-11 11:26:05 IP:140.113.xxx.xxx 未訂閱
引言: 真抱歉 我的舉例,我的目的 傳遞不好 讓您浪費不少時間 其實是我沒功力 才會這麼多奇怪問題 把 int a[100] 當成 char a[400] 來看 對於超過 255 的數值 把它切割 好像沒什意義 只是舉例而已 void clear_buffer(char *ptr ,int length) { for(w=0; w<=length-1; w ) w 沒宣告 { ptr[w]=0; } } main() ( int a[100]; struct tm t; memset(a,1,sizeof[a]) ; 這邊應該是sizeof(a),是小括號 // a 雖是 int* 但傳入 memset 後 就是以 char* 型態處理 // 出來後 a[0] 可不是 0001 而是 1111 根據 memset 的定義是 void *memset(void *s, int c, size_t n); 所以傳進去的第一個引數只是一個記憶體位置,跟型別無關 編譯器會自動幫你轉換指標型別為 void* 操作上是以byte為單位沒錯 clear_buffer(a,sizeof[a]); // Borland C 5.0 已不准 int* 轉成 char* 有一種東西叫做強制轉型 這裡寫成 clear_buffer((char *)a,sizeof(a)); 就沒錯 clear_buffer(&t,sizeof[t]); // int* 只能對應到相等的 int* // 可是 memset 是可以的 ) 不過 只是覺得 int (*ptr)[10] 中途 可以把 10 改變 成其他 值 應該 會很實用 /////////////////////////// char (*ptr2)[10]; ptr2 = (char *)malloc(100); borland C 5.0 編譯也是 時而可行 時而不行(can not convert (char *)to (char *)[10] ) 我也只好不用這種方法了 /////////////////////////// 這樣是一定有問題的 ptr2 的型別是 char** malloc 傳回的只是 char* 編譯會過才奇怪! 雖然都是指標,只是記憶位置,但是意義上完全不同(char** 與 char*) c 好早好早就有了 而且幾乎都用 c 等到發現它有些不方便之處 有心想改變 它 可能也不容易 因為大變動 可能讓以前 的程式碼 不能相容 void _routine(int x,int y) { int aa[x][y]; } 等到讀到 x,y 值 才決定 "堆疊" 大小 難道辦不到嗎 ? 一定辦得到的 應該是 如你所說的 c 規範 或 某些顧慮 或 速度考量 ....
看完前面一長串,實在不清楚quickcccc您對「int (*ptr)[10] 中途 可以把 10 改變 成其他 值 應該 會很實用」或是「請問: 如何任意改變 成 (*ptr)[10] 或 (*ptr)[20] .... 以便 陣列 列數*行數 可以任意變動」的目的在哪裡。只要透過指標的操作,問題就可以解決了。
int ptr[20][5];    // 走訪每一個元素,直覺上會用
for(int i = 0; i < 20; i  )
  for(int j =0; j < 5; j  )
    ptr[i][j]; // *((int*)ptr   i*5   j)    // 但是,若用指標,也可以改成
for(int i = 0; i < 10; i  )
  for(int j = 0; j < 10; j  )
    *((int*)ptr   i*10   j);    // 當然,也可以看成一維的....
for(int i = 0; i < 100; i  )
  *((int*)ptr   i);
有誤請指正,謝謝
quickcccc
一般會員


發表:3
回覆:15
積分:3
註冊:2005-08-04

發送簡訊給我
#16 引用回覆 回覆 發表時間:2005-08-11 13:20:22 IP:203.70.xxx.xxx 未訂閱
====================================================== 看完前面一長串,實在不清楚quickcccc您對「int (*ptr)[10] 中途 可以把 10 改變 成其他 值 應該 會很實用」或是「請問: 如何任意改變 成 (*ptr)[10] 或 (*ptr)[20] .... 以便 陣列 列數*行數 可以任意變動」的目的在哪裡。只要透過指標的操作,問題就可以解決了。 ====================================================== 方法一 先配置一維的指標陣列 在另外逐一的配置記憶塊 方法二 如 arisaka_matsuri 你所說 的方法 我都是用 arisaka_matsuri 你說的方法 (而且用的地方非常多) 但是一旦程式出現很麻煩的 bug 而且又出現在這附近 就會感到很疑惑 一直想是否 -*/ 出錯嗎 是嗎? 是嗎? 是嗎? 如果今天用的是 3 維(x,y,z) 式子會變的更複雜 一旦有 bug 就會一直懷疑是否這裡出錯 當然最後還是得實際測試 搞了半天 結果沒寫錯 只好再往別處找 int row,col; int (*ptr)[78]; row = 100; col = 78; ptr = (int *) malloc ( sizeof(int)* row * col); 當我想存取某個位置時 只要使用 ptr_2[x][y] 就可以了 那些 x,y 之間的 加減乘除 就交改系統背後自行去計算 如此一來 式子簡潔了 當 bug 發生時 也容易看出來 當我改變 row,col 時 int (*ptr_2)[311]; row = 88; col = 311; ptr = (int *) malloc ( sizeof(int)* row * col); 當我想存取某個位置時 只要使用 ptr_2[x][y] 就可以了 ============================================================ c 提供 像 int (*ptr_2)[78]; 這種寫法 只是一旦宣告 成 78 就無法在改變這個 78 正因 c 提供這種寫法 所以讓我想說 是否有辦法 改變 這個 78 的 "只是我不知如何改而已" 如果能改的話 就不需要去計算 x,y 之間的加減乘除 交改系統去計算就可以了~~~~~~
arisaka_matsuri
高階會員


發表:25
回覆:205
積分:231
註冊:2003-10-19

發送簡訊給我
#17 引用回覆 回覆 發表時間:2005-08-11 18:57:41 IP:140.113.xxx.xxx 未訂閱
引言: c 提供 像 int (*ptr_2)[78]; 這種寫法 只是一旦宣告 成 78 就無法在改變這個 78 正因 c 提供這種寫法 所以讓我想說 是否有辦法 改變 這個 78 的 "只是我不知如何改而已" 如果能改的話 就不需要去計算 x,y 之間的加減乘除 交改系統去計算就可以了~~~~~~
答案不是很清楚嗎? 如果可以這樣改,您應該早就會了! 如果說要交由系統改,也不是沒有 C 裡就提供了 vector 跟 list 這類的 container 不過,原理也是很清楚,還是配置一塊新的記憶體,然後搬來搬去之類的 最後,我認為指標好不好用端看個人 您說那指標加加減減,容易出問題 我倒是持相反的意見 這種類似組語的操作方式,不是更能代表你如何去看待記憶體中的資料嗎? 只能說習慣不同,我現在看 a[x][y] 這種東西反而越來越不習慣 而用這種指標加加減減來操作,兩年來我不知道什麼是 bug 我不否認這是因為學過組語帶來的效應 而C正是保有高階語言的優點與組語的威力,所以寫起來才會令人愉快吧! 提供給您參考
quickcccc
一般會員


發表:3
回覆:15
積分:3
註冊:2005-08-04

發送簡訊給我
#18 引用回覆 回覆 發表時間:2005-08-11 21:15:45 IP:61.59.xxx.xxx 未訂閱
答案不是很清楚嗎? 如果可以這樣改,您應該早就會了! ========================== 就是因為覺得可能我所知不足 要不然何需來問 ========================== 您說那指標加加減減,容易出問題 我倒是持相反的意見 這種類似組語的操作方式,不是更能代表你如何去看待記憶體中的資料嗎? ========================== 如果指標真那完美 幹麻要有 Java 系統 Java 它幹麻刪除了指標 ,幹麻自動來管理或清除記憶體, 因為網路需要更安全 所以指標好不好用 還是得看地方啦 如果一個能夠提供較快捷的方法卻不用 那還學 c 幹麻 函式庫 也不要用啦 MFC 也不要學啦 還是繼續用 SDK 好了 乾脆 您自己通通用 c, assembly 全部自己寫一套自己的 SDK 而且相容微軟 window 系統 如果您還是天下第一等利害 連 c 也不需用啦 通通像寫IC 用assembly 就可以蓋出你的 window 世界 如此一來 不旦達到如您所說的 "代表你如何去看待記憶體中的資料" 我看還是達到 超級滾花爛熟 世界級神乎其技 的境界 ========================== 這個話題 就此打住 免的沒完沒了 ==========================
powmien
初階會員


發表:27
回覆:80
積分:41
註冊:2004-10-20

發送簡訊給我
#19 引用回覆 回覆 發表時間:2005-08-12 09:31:06 IP:59.112.xxx.xxx 未訂閱
引言: 如果指標真那完美 幹麻要有 Java 系統 Java 它幹麻刪除了指標 ,幹麻自動來管理或清除記憶體, 因為網路需要更安全 所以指標好不好用 還是得看地方啦 如果一個能夠提供較快捷的方法卻不用 那還學 c 幹麻 函式庫 也不要用啦 MFC 也不要學啦 還是繼續用 SDK 好了 乾脆 您自己通通用 c, assembly 全部自己寫一套自己的 SDK 而且相容微軟 window 系統 如果您還是天下第一等利害 連 c 也不需用啦 通通像寫IC 用assembly 就可以蓋出你的 window 世界 如此一來 不旦達到如您所說的 "代表你如何去看待記憶體中的資料" 我看還是達到 超級滾花爛熟 世界級神乎其技 的境界 ========================== 這個話題 就此打住 免的沒完沒了 ==========================
在看到您對我這笨蛋腦袋瓜想出來的程式批為無意義時 讓修生養性極差的我,說了很多不該說的話,對不起。 看到您有舉例同一個語法在不同的Compiler上有些能過 有些不能過,所以我也舉了我在IAR-C compiler上面遇 到了跟一般C compiler上較為不同的BUG,對不起。 身為一個初學者還建議您去了解 程式底層在幹什麼, 可以嘗試寫出自已要的東西(VCL、object..etc),對不起。 還有看待記憶体中的資料這句極沒知識的話是我說的, 不過我真的沒提到用組語或寫Chip的C能跟Windows這 宏偉的架構能搭上邊< >。 到頭來還真的是完全牛頭對不上馬嘴< > 天下英雄出我輩,一入江湖歲月催; 皇圖霸業談笑中,不勝人生一場醉。
quickcccc
一般會員


發表:3
回覆:15
積分:3
註冊:2005-08-04

發送簡訊給我
#20 引用回覆 回覆 發表時間:2005-08-12 20:05:05 IP:61.59.xxx.xxx 未訂閱
for powmien ===================================== // < powmien 你提到 > 到頭來還真的是完全牛頭對不上馬嘴 ===================================== 經此一役 感同身受 所以才會有那麼麼多誤解 再此一一澄清 不說清楚 你心理會不好受的 ===================================== // < powmien 你提到 > 還有看待記憶体中的資料這句極沒知識的話是我說的, ===================================== 不是你說的 是 arisaka_matsuri說的 其餘 那些 /如果一個能夠提供較快捷的方法卻不用 那還學 c 幹麻 /函式庫 也不要用啦 MFC 也不要學啦 還是繼續用 SDK 好了 /乾脆 您自己通通用 c, assembly 全部自己寫一套自己的 SDK 這也是對 arisaka_matsuri 說的 不是對 powmien 你說的 ===================================== // 看< powmien 你提到 > 到您有舉例同一個語法在 // 不同的Compiler上有些能過 // 有些不能過,所以我也舉了我在IAR-C compiler上面遇 // 到了跟一般C compiler上較為不同的BUG,對不起。 ===================================== 我是說 int *ptr[100] = (int *)ptrmalloc(100); 早上用 BC5 不僅編譯成功 而且還可以跑 晚上我再用 BC5 編譯 , BC5卻告訴我 不准許這種寫法 我手邊是沒有 VC 也沒去抓 Dev C 來測試 如果三位c 都說 NO , 那大概就是已經不能這樣寫了 ===================================== // < powmien 你提到 >在看到您對我這笨蛋腦袋瓜想出來的程式批為無意義時 // 讓修生養性極差的我,說了很多不該說的話,對不起。 ===================================== 我不是那種囂張到會把別人程式批為無意義 來此請益 卻讓熱心回覆者跟我道歉 說不過去 [首先] powmien 你提到的 [先配置一維的指標陣列 在另外逐一的配置記憶塊 如果配置失敗 再逐一釋放] 我沒有說是無意義 這個配置2維的方法 我在一本10年前的雜誌曾看過 裡面也提到這個方法的一些優點 所以不會無意義 例如: 記憶體可為不連續 可以不用 Huge 編譯模式就可以擁有超越 64k 記憶體 當然那是 Dos 才有Huge這種東西 [其次] powmien 你用下列方法 去一一讀取integer的4個byte temp= (ptr[vv][c]&0xff); temp= ((ptr[vv][c]&0xff00)>>8); temp= ((ptr[vv][c]&0xff0000)>>16); temp= ((ptr[vv][c]&0xff000000)>>24); 這個方法我自己也用啦,所以我不是指你的程式無意義,你天大誤會啦 ~~~~~~~~~ 以前我自己也是用這個方法, 那我豈不是自己罵自己呢? 那時因為 Dos 記憶體太小, 所以我把1 byte 切成一半當 4 bit 用,雖然麻煩,但是還得做 能不能再切下去,答案是不能. 因為我資料數值範圍是 0 ~ 15 所以在提問中,我確實講了『好像沒什意義』 至於我我是指什麼已經不重要 重要的是要告訴您:絕對不是指你的程式無意義, 因為這個方法我自己都在用 今天要不是powmien你說: 『在看到您對我這笨蛋腦袋瓜想出來的程式批為無意義時 讓修生養性極差的我.......』 說實在的,之前我只知道你在生氣, 可是我真的完全不知道你在生氣什麼 因為我根本不知道,我這句『好像沒什意義』, 會讓你誤以為是指『你寫的程式被批為無意義』 完全是訊息交換有誤, 才會造成你的誤解, 真是抱歉
系統時間:2024-05-18 6:46:51
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!