用随机数字和字母初始化c中的2d矩阵

时间:2015-10-08 19:13:34

标签: c arrays pointers double

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;

提供了这个双指针。它应该指向某些东西,但我不确定它应该指向什么。任何见解或解释都会非常有帮助。我已经尝试查找双指针并理解,例如,如果你有一个字符列表,你可以使用类似* word的东西,如果你想要一个句子就可以从那里做**指向单词的句子。不知道这是如何延续的。

    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;
}

3 个答案:

答案 0 :(得分:0)

指针指向一块内存。要将一个用作数组,必须分配内存。

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

我创建了一个包含10个Square和ptr点的数组到这个数组的第一个Square。通过编写ptr [2]来访问第三个Square。

继续双指针。他们指向其他指针。想象一下矩阵。

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

p1 [0]指向指向第一个数组的指针。 p1 [1]指向第二个,依此类推。为了更好地理解指针,您可以将它们视为n维数组,其中n是星数。

答案 1 :(得分:0)

好的,很明显,你需要帮助克服C的第一部分使用/引用动态分配的内存,所以让我们来看看基础知识。但是,在我们查看代码之前,让我们谈谈你将如何编译代码。您需要在编译时启用警告,然后在考虑完成代码之前消除所有警告。警告可以帮助您。您至少要在使用-Wall -Wextra时启用gcc,您可以检查其他编译器的等效项。您的编译字符串类似于:

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

-g将为gcc生成用于调试的符号。完成调试后,您需要将-g替换为所需的优化级别0(零,默认值)或1, 2, 3, fast。您可以使用大写-O指定选项(哦,不是零)(例如-O3-Ofast(gcc 4.6和更新))。

现在知道如何构建代码,让我们看看如何编写代码。首先,在C中,有没有 2D数组。只有方法可以模拟2D数组的索引。当您使用指针数组(例如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);
    ...
}

您现在已声明ROWSCOLS数字类型Square数组的指针数。这允许您模拟 2D阵列,即使不要求任何阵列在内存中是连续的。

注意: calloc用于分配指针。 calloc分配并初始化为NULL(或0)。每次分配内存块时,都需要验证分配成功。您可以通过检查malloccallocrealloc - 每次的回报来执行此操作。 E.g:

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

您可以创建一个辅助函数来分配/检查并返回指向新内存块的指针,以保持代码整洁。

分配并验证内存块后,

注2: 您的责任 (1。)保留指向该内存块的起始地址,以便(2。)当您不再需要时,可以释放该内存块。

对于1D数组,事情要简单得多,您只需为所需类型Square分配存储空间即可。 E.g:

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

您可以通过简单地创建允许2D数组类型索引引用连续数组中任何位置的逻辑来模拟此分配中的2D数组。 (看起来像matrix[row*ROWS+col] 0 <= row < ROWS)。虽然不是下面示例的一部分,但如果您确实想要从matrix2模拟2D数组,那么为了完整起见,您可以按如下方式实现打印数字部分:

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');
}

Note2 中的(1。)是什么意思?这意味着你必须特别注意不要做以下事情:

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

内存泄漏/错误检查

在任何动态分配内存的代码中,必须使用内存错误检查程序。对于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)

答案 2 :(得分:-1)

首先必须定义ROWSCOLUMNS

然后为矩阵分配内存:

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

最后更正this Square.i[row][column]=rand()%10; 这个matrix[row][column].i=rand()%10;