gpt4 book ai didi

c - C 中的段错误

转载 作者:行者123 更新时间:2023-12-05 04:19:33 25 4
gpt4 key购买 nike

我在编码方面很新,所以不要太挑剔,如果我犯了一个简单的错误......我是自学成才的,所以你是我唯一可以问的人。感谢所有愿意提供帮助的人!

我正在尝试用 制作类似“太空射击游戏”的东西,但它总是给我写段错误,我不明白为什么。我想我可以给你我所有的代码,这样你就可以理解游戏的逻辑,但我认为我的问题可能是从 curses 初始化开始到结束......也许我错过了 refresh() 或类似的东西?

#include <stdio.h>
#include <stdlib.h>
#include<curses.h>
#include<time.h>
#include<string.h>
#include<unistd.h>

int main()
{
int sizey = 23;
int sizex = 40;
int x, y, yi;
char world[sizey][sizex];
char player = 'A';
char playerLaser = '^';
char enemy = 'M';
char enemyShielded = 'O';
char enemyLaser = 'U';
char explosion = 'X';
int score = 0;
int victory = 1;
int laserReady = 1;
int enemyReady = 0;

srand(time(NULL));

/*welcome screen*/
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
nodelay(stdscr,TRUE);
printf("\n \n Welcome soldier! \n \n \n \n");
usleep(1*100000);
printf(" Brave the COMMAND PROMPT INVADERS and come back a hero. \n \n \n \n");
usleep(1*10000);
printf(" Your operating system is depending upon you. \n \n \n \n");
usleep(1*10000);
printf(" Good luck.");
usleep(1*10000);
printf("\n \n \n \n Press any key to start.");
getch();
/*initialise world*/
int totalEnemies = 0;
for (x = 0; x < sizex; x ++) {
for (y = 0; y < sizey; y ++) {
if ((y+1) % 2 == 0 && y < 7 && x > 4
&& x < sizex - 5 && x % 2 ==0) {
world[y][x] = enemy;
totalEnemies ++;
}
else if ((y+1) % 2 == 0 && y >= 7 && y < 9 && x > 4
&& x < sizex - 5 && x % 2 ==0){
world[y][x] = enemyShielded;
totalEnemies = totalEnemies + 2;
}
else {
world[y][x] = ' ';
}
}
}
world[sizey - 1][sizex / 2] = player;
int i = 1;
char direction = 'l';
int currentEnemies = totalEnemies;
while(currentEnemies > 0 && victory) {
int drop = 0;
int enemySpeed = 1 + 10 * currentEnemies / totalEnemies;
laserReady ++;
refresh();
endwin();

/*display world*/
system("clear");
printf(" SCORE: %d", score);
printf("\n");
for (y = 0; y < sizey; y ++) {
printf("|");
for (x = 0; x < sizex; x ++) {
printf("%c",world[y][x]);
}
printf("|");
printf("\n");
}
/*laser time*/
for (x = 0; x < sizex; x ++) {
for (y = sizey-1; y >= 0; y --) {
if (i%2 == 0 && world[y][x] == enemyLaser
&& (world[y+1][x] != enemy & world[y+1][x] != enemyShielded)){
world[y+1][x] = enemyLaser;
world[y][x] = ' ';
}
else if (i%2 == 0 && world[y][x] == enemyLaser
&& (world[y+1][x] == enemy | world[y+1][x] == enemyShielded)){
world[y][x] = ' ';
}
}
}
for (x = 0; x < sizex; x ++) {
for (y = 0; y < sizey; y ++) {
if ((i % 5) == 0 && (world[y][x] == enemyShielded
| world[y][x] == enemy) && (rand() % 15) > 13
&& world[y+1][x] != playerLaser) {
for (yi = y+1; yi < sizey; yi ++) {
if (world[yi][x] == enemy
| world[yi][x] == enemyShielded) {
enemyReady = 0;
break;
}
enemyReady = 1;
}
if (enemyReady) {
world[y+1][x] = enemyLaser;
}
}
if (world[y][x] == playerLaser && world[y-1][x] == enemy) {
world[y][x] = ' ';
world[y-1][x] = explosion;
currentEnemies --;
score = score + 50;
}
else if (world[y][x] == playerLaser
&& world[y-1][x] == enemyShielded) {
world[y][x] = ' ';
world[y-1][x] = enemy;
currentEnemies --;
score = score + 50;
}
else if (world[y][x] == playerLaser
&& world[y-1][x] == enemyLaser) {
world[y][x] = ' ';
}
else if (world[y][x] == explosion) {
world[y][x] = ' ';
}
else if ((i+1) % 2 == 0 && world[y][x] == enemyLaser
&& world[y+1][x] == player) {
world[y+1][x] = explosion;
world[y][x] = ' ';
victory = 0;
}
else if (world[y][x] == playerLaser
&& world[y-1][x] != enemyLaser) {
world[y][x] = ' ';
world[y-1][x] = playerLaser;
}
}
}

/*update enemy direction*/
for (y = 0; y < sizey; y ++) {
if (world[y][0] == enemy) {
direction = 'r';
drop = 1;
break;
}
if (world[y][sizex-1] == enemy){
direction = 'l';
drop = 1;
break;
}
}

/*update board*/
if (i % enemySpeed == 0) {
if (direction == 'l') {
for (x = 0; x < sizex - 1; x ++) {
for (y = 0; y < sizey; y ++) {
if (drop && (world[y-1][x+1] == enemy
|| world[y-1][x+1] == enemyShielded)){
world[y][x] = world[y-1][x+1];
world[y-1][x+1] = ' ';
}
else if (!drop && (world[y][x+1] == enemy
|| world[y][x+1] == enemyShielded)) {
world[y][x] = world[y][x+1];
world[y][x+1] = ' ';
}
}
}
}
else {
for (x = sizex; x > 0; x --) {
for (y = 0; y < sizey; y ++) {
if (drop && (world[y-1][x-1] == enemy
|| world[y-1][x-1] == enemyShielded)) {
world[y][x] = world[y-1][x-1];
world[y-1][x-1] = ' ';
}
else if (!drop && (world[y][x-1] == enemy
|| world[y][x-1] == enemyShielded)) {
world[y][x] = world[y][x-1];
world[y][x-1] = ' ';
}
}
}
}
for (x = 0; x < sizex; x ++) {
if (world[sizey - 1][x] == enemy) {
victory = 0;
}
}
}

/*control player*/
int ch;
ch = getch();
if(ch == 'a'){
for (x = 0; x < sizex; x = x+1) {
if ( world[sizey-1][x+1] == player) {
world[sizey-1][x] = player;
world[sizey-1][x+1] = ' ';
}
}
}

if(ch == 'd'){
for (x = sizex - 1; x > 0; x = x-1) {
if ( world[sizey-1][x-1] == player) {
world[sizey-1][x] = player;
world[sizey-1][x-1] = ' ';
}
}
}
if(ch == 'm'&& laserReady > 2){
for (x = 0; x < sizex; x = x+1) {
if ( world[sizey-1][x] == player) {
world[sizey - 2][x] = playerLaser;
laserReady = 0;
}
}
}
i ++;
usleep(1*100000);
}
system("clear");
printf(" SCORE: %d", score);
printf("\n");
for (y = 0; y < sizey; y ++) {
printf("|");
for (x = 0; x < sizex; x ++) {
printf("%c",world[y][x]);
}
printf("|");
printf("\n");
}
usleep(1*100000);
system("clear");
if (victory != 0) {
printf("\n \n \n \n \n \n CONGRATULATIONS! \n \n \n \n \n");
usleep(1*100000);
printf("\n \n Score: %d", score);
usleep(1*100000);
int bonus = totalEnemies*20 - i;
printf("\n \n Bonus: %d", bonus);
usleep(1*100000);
printf("\n \n Total Score: %d", score + bonus);
printf("\n \n \n \n Well done");
usleep(1*100000);
printf(", Hero.");
usleep(1*100000);
getch();
}
else {
printf("\n \n \n \n \n \n You have failed.");
usleep(1*100000);
printf("\n \n \n \n \n \n Windows is doomed.");
usleep(1*100000);
printf("\n \n Final Score: %d", score);
getch();
}
}

最佳答案

正如上面评论中所说:这不是诅咒问题。相反,在多种情况下您尝试访问 world[][] 数组之外的元素,这就是导致段错误的原因。我没有遍历每个实例,但例如,考虑“控制播放器”部分。在“a”(左)处理程序中,您正确地将单元格范围从 0 到(但不包括)sizex...然后(有时)修改偏移量 sizex 处的单元格,这是越界的。

您可以以一种边界安全的方式重写此部分,顺便说一句更高效:

int playerx = sizex / 2;  /* at main() start -- track the player's
position instead of looking through the
line to find it each time */
...

/* control player */
int ch;
ch = getch();

if (ch == 'a' && playerx > 0) {
playerx--;
world[sizey - 1][playerx] = player;
world[sizey - 1][playerx + 1] = ' ';
}

if (ch == 'd' && playerx < sizex - 1) {
playerx++;
world[sizey - 1][playerx] = player;
world[sizey - 1][playerx - 1] = ' ';
}

if (ch == 'm' && laserReady > 2) {
world[sizey - 2][playerx] = playerLaser;
laserReady = 0;
}

请注意,这只是需要检查边界的一个地方。

同时,因为这个标记为 curses...请注意,整个程序可以很容易地转换为 curses:

  1. printf() 的所有实例更改为 printw()
  2. system(clear) 的所有实例更改为 erase()
  3. usleep() 更改为 napms()(除以 1000)。
  4. endwin()移动到最后。
  5. 在第一个 getch() 之后移动 nodelay()
  6. 在最后一个erase()之后添加一个nodelay(stdscr, FALSE)

进一步的调整将使其工作得更好。

关于c - C <curses.h> 中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74779856/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com