2015-10-08 67 views
0
typedef struct square 
{ 
    int i; 
    char c; 
} Square; 


Square** initializeMatrix(void); 
void printMatrixNumbers(Square**); 
void printMatrixLetters(Square**); 
void shuffleMatrix(Square**); 

Square* initialize1DMatrix(void); 
void print1DMatrixLetters(Square*); 
void print1DMatrixNumbers(Square*); 
void shuffle1DMatrix(Square*); 



int main(void) 
{ 
    srand(time(NULL)); 

    Square** matrix = initializeMatrix(); 

    while(1) 
    { 
     printf("Print which set?: "); 
     printf("\n1. letters\n2. numbers\n3. shuffle matrix\n4. move to 1D matrix"); 
     printf("\n>"); 
     int choice; 
     scanf("%d", &choice); 

     if(choice == 1) 
     { 
      printMatrixLetters(matrix); 
     } 
     else if(choice == 2) 
     { 
      printMatrixNumbers(matrix); 
     } 
     else if(choice == 3) 
     { 
      shuffleMatrix(matrix); 
     } 
     else if(choice == 4) 
     { 
      break; 
     } 
     else 
     { 
      printf("Didn't understand that input. Try again\n\n"); 
     } 
    } 

    Square* matrix2 = initialize1DMatrix(); 
    printf("\n\nNow for the 1D array:\n\n"); 

    while(1) 
    { 
     int choice; 
     printf("Print which set?: "); 
     printf("\n1. letters\n2. numbers\n3. shuffle matrix\n4. quit"); 
     printf("\n>"); 
     scanf("%d", &choice); 

     if(choice == 1) 
     { 
      print1DMatrixLetters(matrix2); 
     } 
     else if(choice == 2) 
     { 
      print1DMatrixNumbers(matrix2); 
     } 
     else if(choice == 3) 
     { 
      shuffle1DMatrix(matrix2); 
     } 
     else if(choice == 4) 
     { 
      break; 
     } 
     else 
     { 
      printf("Didn't understand that input. Try again\n\n"); 
     } 
    } 

    return 0; 
} 




Square** initializeMatrix() 
{ 
    //this will be used to randomize the matrix. See below for more info. 
    char letters[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; 


    int row, column; 


    Square** matrix; 

提供了這個雙指針。它應該指向某些東西,但我不確定它應該指向什麼。任何見解或解釋都會非常有幫助。我嘗試過查找雙指針,並理解,例如,如果你有一個字符列表,你可以使用類似*的單詞,並從那裏如果你想要一個句子,你可以做**句子指向單詞。不知道這是如何繼續。用c和隨機數字和字母初始化2d矩陣

for(row = 0; row < ROWS; row++) 
    { 

應該是做這件事,不知道什麼,但。這是指針數組獲取自己的元素數組嗎? }

 for(row = 0; row < ROWS; row++) 
    { 
      for(column = 0; column < COLUMNS; column++) 
      { 

這裏就是我需要生成隨機數字和字母,然後給那個數字和字符的矩陣。下面,我在','令牌之前得到預期的標識符或')'。爲什麼是這樣?

    srand(time(NULL)); 
        Square.i[row][column]=rand()%10; 


      } 

    }  




return matrix; 
} 
+0

看[**上的2D陣列C **使用的realloc](http://stackoverflow.com/questions/33007171/using-realloc-on-a-2d-array-c/33011568# 33011568)。你可以添加字母。 –

+1

沒有二維數組aka矩陣。 'Square **'是**不是**數組! – Olaf

回答

0

指針指向一塊內存。爲了使用一個作爲數組,你必須分配內存。

Square *ptr = malloc(sizeof(Square) * 10) 

我已經創建了一個10個Square和ptr點數組到這個數組的第一個Square。訪問第三個Square是通過編寫ptr [2]來完成的。

移動到雙指針。他們指向其他指針。想象一下矩陣。

Square **p1; 
**p1 = malloc(sizeof(Square) * 10) 
*p1 = malloc(sizeof(Square*) * 10) 

p1 [0]指向指向第一個數組的指針。 p1 [1]指向第二個,依此類推。爲了更好地理解指針,你可以把它們想象成n維數組,其中n是星的數量。

+0

請不要投malloc'和朋友'返回:https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc –

+0

@Jens Gustedt謝謝你的建議! –

+0

哦,好吧。我明白。爲什麼我們需要指向指針?爲什麼我們不能簡單地使用指針地址? – Joe

-1

你首先要確定ROWSCOLUMNS

則矩陣分配內存:

matrix=malloc(sizeof(quare)* ROWS*COLUMNS); 

最後正確this Square.i[row][column]=rand()%10; 這個matrix[row][column].i=rand()%10;

+0

謝謝! This Square [row] [column] .i = rand()%10;仍然會得到和以前一樣的錯誤:'['之前的預期標識符。爲什麼是這樣? – Joe

+0

對不起,請將'Square'更改爲'matrix'。謝謝你的評論 – milevyo

+0

做**不** **'malloc'的返回。它不過是一個內存地址。它沒有「類型」。正確的分配是矩陣= malloc(ROWS * sizeof *矩陣)'然後'矩陣[我] = malloc(COLUMNS * sizeof **矩陣)'。然後你分配矩陣[i] [j]' –

0

好吧,這是顯而易見的,你需要幫助使用/引用動態分配的內存來克服C的第一部分,所以讓我們看看基本知識。但是,在我們看代碼之前,讓我們先談談你將如何編譯它。您需要在編譯時啓用警告,然後在您考慮完成代碼之前取消所有警告。警告會幫助你。至少你想在使用gcc時啓用-Wall -Wextra,你可以檢查其他編譯器的等價物。你的編譯字符串將類似於:

gcc -Wall -Wextra -g -o square square.c 

-g將生成調試符號與gcc。當您完成調試時,您將需要用您想要的優化級別0(零,默認值)或1, 2, 3, fast替換-g。您指定的首選項爲-O(哦,不爲零)(例如-O3-Ofast(gcc 4.6及更新版本))。

現在知道你將如何構建你的代碼,讓我們看看如何編寫它。首先,在C中,有沒有二維數組。只有方法可以模擬二維數組的索引。當使用一個數組指針的輸入(例如Square **matrix),以模擬2D陣列的方法是聲明和分配指針數組鍵入Square

Square **matrix = NULL; 
matrix = calloc (ROWS, sizeof *matrix); 

這將聲明ROWS數目的指向類型爲Square*的矩陣的指針。然後,每個指針,你分配的內存塊持有struct Square所需數量:

for (row = 0; row < ROWS; row++) 
{ 
    matrix[row] = malloc (COLS * sizeof **matrix); 
    ... 
} 

您現在已經宣佈ROWS數指針到COLS數量型Square的陣列。這允許你模擬一個二維數組,即使沒有要求任何數組在內存中是連續的。

注意:calloc被用來分配指針。 calloc都分配並初始化爲NULL(或0)。每當你分配一塊內存時,你需要驗證分配成功。您可以通過檢查malloc,callocrealloc - 的返回來完成此操作,每次都檢查。例如: -

matrix = calloc (ROWS, sizeof *matrix); 
if (!matrix) { 
    fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__); 
    exit (EXIT_FAILURE); 
} 

您可以創建一個輔助函數來分配/檢查,並返回一個指向新的內存塊,以保持你的代碼整潔。

注2:你分配和驗證的內存塊後,它是你的責任(1)保存一個指向內存中,以便(2)該塊的起始地址當您不再需要時,可以釋放該內存塊。

對於你的1D數組,事情要簡單得多,你只需要爲需要的Square類型的數量分配存儲空間。例如爲:

matrix = calloc (ROWS * COLS, sizeof *matrix); 

可以通過簡單地創建邏輯,允許2D陣列類型的索引來指代任何位置連續陣列內模擬從該分配的2D陣列,以及。 (它看起來像matrix[row*ROWS+col],其中0 <= row < ROWS)。雖然不是下面的示例中的一部分,如果你是想從您matrix2模擬二維數組,然後爲了完整起見如下你可以實現打印部件號:

void print1DMatrixAs2DNumbers (Square *matrix) 
{ 
    if (!matrix) return; 

    int row, col; 

    printf ("\n simulated 2D array numbers are:\n\n"); 
    for (row = 0; row < ROWS; row++) { 
     for (col = 0; col < COLS; col++) 
      printf (" %4d", matrix[row * ROWS + col].i); 
     putchar ('\n'); 
    } 
    putchar ('\n'); 
} 

什麼(1) in 備註2是什麼意思?這意味着你必須特別注意不要做類似如下:

while (1) { 
    ... 
    matrix++; 
} 

當您使用的循環中完成,道出了什麼的內存塊的開始您最初分配的?沒有。如果您沒有起始地址,則該內存不能再被釋放。如果您發現自己處於這種情況,請創建一個指向矩陣的指針並在循環中使用它。 (例如Square *p = matrix;,然後while (1) {... p++;}

這些是做你正在做的事情的基礎知識。其餘部分僅僅是語法和整理你的程序邏輯。是的,我知道你也需要幫助。

下面是一個例子,暗示你的代碼。它旨在告訴你如何把這些作品放在一起,而不是爲你做。 C是一種非常優雅和靈活的低級語言,可以爲機器提供強大的動力和控制力,除了彙編程序以外,幾乎沒有哪種語言可以提供。有與任何語言相關的學習曲線,C沒有什麼不同。但是,與其他更高級別的語言不同,C可以靈活地執行語法允許的任何操作。沒有任何保護功能可以在數組結束後防止寫入,或在嘗試分配失敗後寫入內存區域。學習C,責任在於你學習C到那個水平,以防止可怕的問題,而不是你賦予你的權力。

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

#define ROWS 8 
#define COLS 8 

typedef struct square 
{ 
    int i; 
    char c; 
} Square; 

Square **initializeMatrix (void); 
void printMatrixNumbers (Square**); 
void printMatrixLetters (Square**); 
void shuffleMatrix (Square**); 

Square *initialize1DMatrix (void); 
void print1DMatrixLetters (Square*); 
void print1DMatrixNumbers (Square*); 
void shuffle1DMatrix (Square*); 

int main (void) 
{ 
    srand (time (NULL)); 

    Square **matrix = initializeMatrix(); 

    while (1) 
    { 
     int choice; 
     printf ("\nPrint which set?: \n\n" 
       " 1. letters\n" 
       " 2. numbers\n" 
       " 3. shuffle matrix\n" 
       " 4. move to 1D matrix\n" 
       " > "); 
     scanf ("%d", &choice); 

     if(choice == 1)   printMatrixLetters (matrix); 
     else if(choice == 2) printMatrixNumbers (matrix); 
     else if(choice == 3) shuffleMatrix (matrix); 
     else if(choice == 4) break; 
     else printf("Didn't understand that input. Try again\n"); 
    } 

    Square *matrix2 = initialize1DMatrix(); 
    printf ("\nNow for the 1D array:\n\n"); 

    while (1) 
    { 
     int choice; 
     printf ("\nPrint which set?: \n\n" 
       " 1. letters\n" 
       " 2. numbers\n" 
       " 3. shuffle matrix\n" 
       " 4. quit\n" 
       " > "); 
     scanf ("%d", &choice); 

     if(choice == 1)   print1DMatrixLetters (matrix2); 
     else if(choice == 2) print1DMatrixNumbers (matrix2); 
     else if(choice == 3) shuffle1DMatrix (matrix2); 
     else if(choice == 4) break; 
     else printf("Didn't understand that input. Try again\n"); 
    } 

    /* free simulated 2D matrix */ 
    size_t i; 
    for (i = 0; i < ROWS; i++) 
     free (matrix[i]); 
    free (matrix); 

    /* free matrix2 */ 
    free (matrix2); 

    return 0; 
} 

Square **initializeMatrix() 
{ 
    /* unless you can't have a null-terminator, this is fine */ 
    char letters[] = "abcdefghijklmnopqrstuvwxyz"; 
    int row, col; 

    Square **matrix = NULL; 

    /* allocate ROWS number of pointers to struct Square 
    * 'calloc' allocates and initializes NULL, you must then 
    * validate your allocation by checking the return. 
    */ 
    matrix = calloc (ROWS, sizeof *matrix); 
    if (!matrix) { 
     fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__); 
     exit (EXIT_FAILURE); 
    } 

    /* allocate COLS number of struct Square and validate */ 
    for (row = 0; row < ROWS; row++) 
    { 
     matrix[row] = malloc (COLS * sizeof **matrix); 

     if (!matrix) { 
      fprintf (stderr, "%s() error: virtual memory exhausted.\n", 
        __func__); 
      exit (EXIT_FAILURE); 
     } 

     for (col = 0; col < COLS; col++) 
     { 
      /* fill i with random number between 0 - 999 */ 
      matrix[row][col].i = rand() % 1000; 

      /* fill c with random letter 'a-z' */ 
      matrix[row][col].c = letters[rand() % 26]; 
     } 
    } 

    return matrix; 
} 

Square *initialize1DMatrix() 
{ 
    /* unless you can't have a null-terminator, this is fine */ 
    char letters[] = "abcdefghijklmnopqrstuvwxyz"; 
    int i; 

    Square *matrix = NULL; 

    /* allocate memory for ROWS * COLS struct Square 
    * and validate 
    */ 
    matrix = calloc (ROWS * COLS, sizeof *matrix); 

    if (!matrix) { 
     fprintf (stderr, "%s() error: virtual memory exhausted.\n", 
        __func__); 
     exit (EXIT_FAILURE); 
    } 

    for (i = 0; i < ROWS * COLS; i++) 
    { 
     /* fill i with random number between 0 - 999 */ 
     matrix[i].i = rand() % 1000; 

     /* fill c with random letter 'a-z' */ 
     matrix[i].c = letters[rand() % 26]; 
    } 

    return matrix; 
} 

void printMatrixNumbers (Square **matrix) 
{ 
    if (!matrix) return; 

    int row, col; 

    printf ("\n simulated 2D array numbers are:\n\n"); 
    for (row = 0; row < ROWS; row++) { 
     for (col = 0; col < COLS; col++) 
      printf (" %4d", matrix[row][col].i); 
     putchar ('\n'); 
    } 
    putchar ('\n'); 
} 

void printMatrixLetters (Square **matrix) 
{ 
    if (!matrix) return; 

    int row, col; 

    printf ("\n simulated 2D array letters are:\n\n"); 
    for (row = 0; row < ROWS; row++) { 
     for (col = 0; col < COLS; col++) 
      printf (" %4c", matrix[row][col].c); 
     putchar ('\n'); 
    } 
    putchar ('\n'); 
} 

void shuffleMatrix (Square **matrix) 
{ 
    if (!matrix) return; 

    fprintf (stderr, "%s() warning: not yet implemented.\n", __func__); 
} 

void print1DMatrixNumbers (Square *matrix) 
{ 
    if (!matrix) return; 

    size_t i; 

    printf ("\n matrix2 numbers are:\n\n"); 
    for (i = 0; i < ROWS * COLS; i++) 
     printf (" matrix2[%2zu] : %4d\n", i, matrix[i].i); 
    putchar ('\n'); 
} 

void print1DMatrixLetters (Square *matrix) 
{ 
    if (!matrix) return; 

    size_t i; 

    printf ("\n matrix2 letters are:\n\n"); 
    for (i = 0; i < ROWS * COLS; i++) 
     printf (" matrix2[%2zu] : %c\n", i, matrix[i].c); 
    putchar ('\n'); 
} 

void shuffle1DMatrix (Square *matrix) 
{ 
    if (!matrix) return; 

    fprintf (stderr, "%s() warning: not yet implemented.\n", __func__); 
} 

編譯

gcc -Wall -Wextra -o bin/square square.c 

使用/輸出

$ ./bin/square 

Print which set?: 

1. letters 
2. numbers 
3. shuffle matrix 
4. move to 1D matrix 
> 2 

simulated 2D array numbers are: 

    180 468 335 205 480 606 40 276 
    360 581 824 731 59 827 573 708 
    837 18 557 109 234 348 255 54 
    527 479 60 174 891 799 868 922 
    35 230 867 335 406 375 660 629 
    416 243 670 948 123 377 607 48 
    943 291 617 263 14 37 419 565 
    126 664 578 357 712 44 738 17 


Print which set?: 

1. letters 
2. numbers 
3. shuffle matrix 
4. move to 1D matrix 
> 1 

simulated 2D array letters are: 

    l  a  f  q  l  e  x  y 
    x  p  y  w  p  w  c  t 
    u  c  h  g  l  q  a  t 
    n  m  a  p  v  s  f  l 
    i  d  l  l  x  j  r  z 
    q  u  t  j  x  p  p  e 
    s  o  s  e  c  q  s  c 
    d  c  k  p  p  p  j  c 


Print which set?: 

1. letters 
2. numbers 
3. shuffle matrix 
4. move to 1D matrix 
> 4 

Now for the 1D array: 


Print which set?: 

1. letters 
2. numbers 
3. shuffle matrix 
4. quit 
> 2 

matrix2 numbers are: 

    matrix2[ 0] : 371 
    matrix2[ 1] : 844 
    matrix2[ 2] : 287 
    matrix2[ 3] : 69 
    matrix2[ 4] : 98 
    matrix2[ 5] : 327 
    matrix2[ 6] : 125 
    matrix2[ 7] : 706 
    matrix2[ 8] : 54 
    matrix2[ 9] : 400 
    ... 
    matrix2[59] : 504 
    matrix2[60] : 655 
    matrix2[61] : 604 
    matrix2[62] : 583 
    matrix2[63] : 597 


Print which set?: 

1. letters 
2. numbers 
3. shuffle matrix 
4. quit 
> 1 

matrix2 letters are: 

    matrix2[ 0] : f 
    matrix2[ 1] : h 
    matrix2[ 2] : u 
    matrix2[ 3] : r 
    matrix2[ 4] : a 
    matrix2[ 5] : u 
    matrix2[ 6] : b 
    matrix2[ 7] : f 
    matrix2[ 8] : y 
    matrix2[ 9] : e 
    ... 
    matrix2[60] : a 
    matrix2[61] : u 
    matrix2[62] : z 
    matrix2[63] : h 


Print which set?: 

1. letters 
2. numbers 
3. shuffle matrix 
4. quit 
> 4 

內存泄漏/錯誤檢查

在任何C在您的寫入動態分配內存時,您必須使用內存錯誤檢查程序。對於Linux valgrind是正常的選擇。濫用一塊可能導致真正問題的內存塊有很多微妙的方法,這樣做是沒有藉口的。每個平臺都有類似的內存檢查器。它們使用簡單。通過它運行你的程序。

$ valgrind ./bin/square 
==9866== Memcheck, a memory error detector 
==9866== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. 
==9866== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info 
==9866== Command: ./bin/square 
==9866== 

Print which set?: 

1. letters 
2. numbers 
3. shuffle matrix 
4. move to 1D matrix 
> 2 

simulated 2D array numbers are: 

    299 713 762 909 504 705 697 846 
    600 735 239  2 870 258 998 155 
    819 88 649 688 921 890  3 657 
    418 52 761 739 17 612 159 664 
    340 264 454 848 49 345 179 359 
    747 958 523 845 398 259 928 240 
    380 963 808 561 253 614 613 733 
    442 222 740 209 228 697 743 777 

<snip> 

Print which set?: 

1. letters 
2. numbers 
3. shuffle matrix 
4. quit 
> 4 
==9866== 
==9866== HEAP SUMMARY: 
==9866==  in use at exit: 0 bytes in 0 blocks 
==9866== total heap usage: 10 allocs, 10 frees, 1,088 bytes allocated 
==9866== 
==9866== All heap blocks were freed -- no leaks are possible 
==9866== 
==9866== For counts of detected and suppressed errors, rerun with: -v 
==9866== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)