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;
}
答案 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);
...
}
您现在已声明ROWS
个COLS
数字类型Square
数组的指针数。这允许您模拟 2D阵列,即使不要求任何阵列在内存中是连续的。
注意: calloc
用于分配指针。 calloc
分配并初始化为NULL
(或0
)。每次分配内存块时,都需要验证分配成功。您可以通过检查malloc
,calloc
或realloc
- 每次的回报来执行此操作。 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)
首先必须定义ROWS
和COLUMNS
然后为矩阵分配内存:
matrix=malloc(sizeof(quare)* ROWS*COLUMNS);
最后更正this Square.i[row][column]=rand()%10;
这个matrix[row][column].i=rand()%10;