使用指针改变矩阵
Using pointers to change a matrix
在我们的 c 课程中,老师给了我们一个构建 "Reversi" 游戏的小项目。我在构建电路板时遇到问题。
#define Size 8
int main()
{
char Board[Size][Size] = { {" "} };
resetBoard(Board);
printBoard(Board);
printf("\n");
getch();
}
void resetBoard(int** board)
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
*(board + (i * Size + j)) = 'x';
}
}
}
void printBoard(int board[Size][Size])
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
printf("%c", board[i][j]);
printf(" ");
}
printf("\n");
}
}
我检查了程序,程序得到:
Run-time check failure #2 - Stack around the variable 'Board' was corrupted
当它更改第三行的第一个 X 时。
例如,如果我 运行 程序直到第 2 行 (16) 的末尾,
我不会收到这个错误。
我认为您的电路板初始化为 char 类型以及在您的函数中使用指针和 int 类型的数组时可能存在问题。 Char 的大小为 1 个字节,而 int 的大小取决于平台(大多数情况下为 4 个字节)。这将导致操作和遍历数组时出现内存问题。
在你的例子中,你似乎在 2 行之后循环遍历了整个分配的内存,因为你使用了 int 类型的指针。在您的情况下,Int 可能比 char 大 4 倍,导致遍历整个 char 类型的数据结构的速度比您预期的快 4 倍。
你的代码中有一堆错误。查看内联评论。
//Use all capitals for defines
#define BOARD_SIZE 8
//Just reset the whole array to spaces.. No need to traverse byte by byte.
void resetBoard(char* board) {
//memset version
//memset(board, ' ', (BOARD_SIZE*BOARD_SIZE)*sizeof(char));
//non memset version
for (int i=0; i<(BOARD_SIZE*BOARD_SIZE); i++) *board++='x';
}
void printBoard(char *board) {
for (int i = 0; i < BOARD_SIZE; i++){
for (int j = 0; j < BOARD_SIZE; j++){
//Access the 2D array like this (y * width of array + x)
printf("%c", board[i*BOARD_SIZE+j]);
printf(" ");
}
printf("\n");
}
}
//Don't start a name using capitals.. Later when you program c++ or similar you will understand :-)
int main()
{
//This is a more dynamic memory model and is not allocated on the stack.. (free when done!!)
char *board=(char*)malloc(BOARD_SIZE*BOARD_SIZE);
//there are several ways of working with arrays.. No need to complicate stuff if not needed.
//Just point out the first byte of the array.. (See the methods takes a char pointer and that is what's passed the methods)
if (board) {
resetBoard(board);
//Test to see if it works
board[1*BOARD_SIZE+2]='0';
printBoard(board);
free(board);
} else {
printf("Out of memory!\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
或者像 2020 年一样闪闪发光!
#define B 16 //Define the size of the 2d matrix
void printMatrix(char*b){for(int i=-1;i<B*B-1;(++i+1)%B?printf("%c ",b[i%B*B+i/B]):printf("%c\n",b[i%B*B+i/B])){}} //Print the 2d matrix
int main(){
char b[B*B]={[0 ...B*B-1]='x'}; //Reserve the 2d matrix space and set all entries to 'x'
printMatrix(&b[0]); //pass the pointer to the print 2d matrix method
return 0; //Done!
}
或 2021 ;-)(二维数组)
#define B 32
void p(char b[B][B]){for(int i=-1;i<B*B-1;(++i+1)%B?printf("%c ",b[i%B][i/B]):printf("%c\n",b[i%B][i/B])){}}
int main(){
char b[B][B]={[0 ...B-1][0 ...B-1]='x'};
p(&b[0]);
}
@RotemHeinig。您的代码有很多不足之处。波纹管是重新格式化您的示例的示例。也许,它会让您了解如何改进工作:
#include<stdio.h>
#define Size 8
void resetBoard(char board[][Size]);
void printBoard(char board[][Size]);
int main()
{
char Board[Size][Size];
resetBoard(Board);
printBoard(Board);
printf("\n");
return 0;
}
void resetBoard(char board[][Size])
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
board[i][j] = 'x';
}
}
}
void printBoard(char board[][Size])
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
printf("%c ", board[i][j]);
printf(" ");
}
printf("\n");
}
}
在我的机器上使用 gcc 编译这段代码看起来像:
gcc -std=c11 -Wall reversi.c -o a.out
并且执行给出:
./a.out
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
希望你能从这里找到灵感。
下面是我之前建议的指针版本:
#include<stdio.h>
#include<stdlib.h>
#define Size 8
void resetBoard(char *board, int size);
void printBoard(char *board, int size);
int main()
{
char *Board = (char *)malloc(Size*Size*sizeof(char));
resetBoard(Board, Size);
printBoard(Board, Size);
printf("\n");
free(Board);
return 0;
}
void resetBoard(char *board, int size)
{
for (size_t i = 0; i < size; i++)
{
for (size_t j = 0; j < size; j++)
{
*(board +i*size + j) = 'x';
}
}
}
void printBoard(char *board, int size)
{
for (size_t i = 0; i < size; i++)
{
for (size_t j = 0; j < size; j++)
{
printf("%c ", *(board +i*size + j));
}
printf("\n");
}
}
编译(在我的机器上)再次看起来像:
gcc -std=c11 -Wall reversi.c -o a.out
并且执行给出:
./a.out
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
在我们的 c 课程中,老师给了我们一个构建 "Reversi" 游戏的小项目。我在构建电路板时遇到问题。
#define Size 8
int main()
{
char Board[Size][Size] = { {" "} };
resetBoard(Board);
printBoard(Board);
printf("\n");
getch();
}
void resetBoard(int** board)
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
*(board + (i * Size + j)) = 'x';
}
}
}
void printBoard(int board[Size][Size])
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
printf("%c", board[i][j]);
printf(" ");
}
printf("\n");
}
}
我检查了程序,程序得到:
Run-time check failure #2 - Stack around the variable 'Board' was corrupted
当它更改第三行的第一个 X 时。 例如,如果我 运行 程序直到第 2 行 (16) 的末尾, 我不会收到这个错误。
我认为您的电路板初始化为 char 类型以及在您的函数中使用指针和 int 类型的数组时可能存在问题。 Char 的大小为 1 个字节,而 int 的大小取决于平台(大多数情况下为 4 个字节)。这将导致操作和遍历数组时出现内存问题。
在你的例子中,你似乎在 2 行之后循环遍历了整个分配的内存,因为你使用了 int 类型的指针。在您的情况下,Int 可能比 char 大 4 倍,导致遍历整个 char 类型的数据结构的速度比您预期的快 4 倍。
你的代码中有一堆错误。查看内联评论。
//Use all capitals for defines
#define BOARD_SIZE 8
//Just reset the whole array to spaces.. No need to traverse byte by byte.
void resetBoard(char* board) {
//memset version
//memset(board, ' ', (BOARD_SIZE*BOARD_SIZE)*sizeof(char));
//non memset version
for (int i=0; i<(BOARD_SIZE*BOARD_SIZE); i++) *board++='x';
}
void printBoard(char *board) {
for (int i = 0; i < BOARD_SIZE; i++){
for (int j = 0; j < BOARD_SIZE; j++){
//Access the 2D array like this (y * width of array + x)
printf("%c", board[i*BOARD_SIZE+j]);
printf(" ");
}
printf("\n");
}
}
//Don't start a name using capitals.. Later when you program c++ or similar you will understand :-)
int main()
{
//This is a more dynamic memory model and is not allocated on the stack.. (free when done!!)
char *board=(char*)malloc(BOARD_SIZE*BOARD_SIZE);
//there are several ways of working with arrays.. No need to complicate stuff if not needed.
//Just point out the first byte of the array.. (See the methods takes a char pointer and that is what's passed the methods)
if (board) {
resetBoard(board);
//Test to see if it works
board[1*BOARD_SIZE+2]='0';
printBoard(board);
free(board);
} else {
printf("Out of memory!\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
或者像 2020 年一样闪闪发光!
#define B 16 //Define the size of the 2d matrix
void printMatrix(char*b){for(int i=-1;i<B*B-1;(++i+1)%B?printf("%c ",b[i%B*B+i/B]):printf("%c\n",b[i%B*B+i/B])){}} //Print the 2d matrix
int main(){
char b[B*B]={[0 ...B*B-1]='x'}; //Reserve the 2d matrix space and set all entries to 'x'
printMatrix(&b[0]); //pass the pointer to the print 2d matrix method
return 0; //Done!
}
或 2021 ;-)(二维数组)
#define B 32
void p(char b[B][B]){for(int i=-1;i<B*B-1;(++i+1)%B?printf("%c ",b[i%B][i/B]):printf("%c\n",b[i%B][i/B])){}}
int main(){
char b[B][B]={[0 ...B-1][0 ...B-1]='x'};
p(&b[0]);
}
@RotemHeinig。您的代码有很多不足之处。波纹管是重新格式化您的示例的示例。也许,它会让您了解如何改进工作:
#include<stdio.h>
#define Size 8
void resetBoard(char board[][Size]);
void printBoard(char board[][Size]);
int main()
{
char Board[Size][Size];
resetBoard(Board);
printBoard(Board);
printf("\n");
return 0;
}
void resetBoard(char board[][Size])
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
board[i][j] = 'x';
}
}
}
void printBoard(char board[][Size])
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
printf("%c ", board[i][j]);
printf(" ");
}
printf("\n");
}
}
在我的机器上使用 gcc 编译这段代码看起来像:
gcc -std=c11 -Wall reversi.c -o a.out
并且执行给出:
./a.out
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
希望你能从这里找到灵感。
下面是我之前建议的指针版本:
#include<stdio.h>
#include<stdlib.h>
#define Size 8
void resetBoard(char *board, int size);
void printBoard(char *board, int size);
int main()
{
char *Board = (char *)malloc(Size*Size*sizeof(char));
resetBoard(Board, Size);
printBoard(Board, Size);
printf("\n");
free(Board);
return 0;
}
void resetBoard(char *board, int size)
{
for (size_t i = 0; i < size; i++)
{
for (size_t j = 0; j < size; j++)
{
*(board +i*size + j) = 'x';
}
}
}
void printBoard(char *board, int size)
{
for (size_t i = 0; i < size; i++)
{
for (size_t j = 0; j < size; j++)
{
printf("%c ", *(board +i*size + j));
}
printf("\n");
}
}
编译(在我的机器上)再次看起来像:
gcc -std=c11 -Wall reversi.c -o a.out
并且执行给出:
./a.out
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x