我們將調試你的代碼在一起。但首先,我會告訴你更多關於如何在論壇上提問的問題(StackOverflow)。
首先沒有'儘可能快',因爲我們都在這裏幫助。我們會盡力而爲,並且可能會也可能不會按時。然後請再次用您的代碼讀取您的消息,並問問自己,這是可讀的嗎?我真的很希望你的代碼在你的文件中看起來不一樣,你只是以某種方式失敗了複製/粘貼,因爲這段代碼是不可讀的。
第一步:更改代碼以使其可讀。
我會跳過此步驟的詳細程度,但基本上它是縮進,需要等時
#include <stdio.h>
#define SIZE 64
struct stack
{
int TowerTop;
int Elem[SIZE];
};
void push(int Elem, struct stack *x);
void pop(struct stack *x);
int create (struct stack *x);
int full(const struct stack *x);
int lolol(struct stack *x, struct stack *x2, struct stack *x3, int a);
int a;
int j;
void main()
{
//scanf("%d", &a);
a = 5;
struct stack Tower1;
struct stack Tower2;
struct stack Tower3;
create(&Tower1);
create(&Tower2);
create(&Tower3);
for (int i = 0; i <= SIZE - 1; i++)
{
Tower1.Elem[i] = 0;
Tower2.Elem[i] = 0;
Tower3.Elem[i] = 0;
}
for (int i = 0; i <= a; i++)
{
Tower1.Elem[i] = i + 1;
}
for (int i = 0; i < a; i++)
{
printf("%d %7d %7d\n", Tower1.Elem[i], Tower2.Elem[i], Tower3.Elem[i]);
}
lolol(&Tower1, &Tower2, &Tower3, a);
printf("%d\n", j);
for (int i = 0; i < a; i++)
{
printf("%d %7d %7d\n", Tower1.Elem[i], Tower2.Elem[i], Tower3.Elem[i]);
}
}
int lolol(struct stack *x, struct stack *x2, struct stack *x3, int a)
{
if (a == 1)
{
printf("\n Disk 1 move to");
push(x->Elem[x->TowerTop], x2->Elem[x2->TowerTop]);
j++;
pop(x->Elem[x->TowerTop]);
return 0;
}
lolol(x, x3, x2, a - 1);
push(x->Elem[x->TowerTop], x2->Elem[x2->TowerTop]);
j++;
pop(x->Elem[x->TowerTop]);
lolol(x3, x2, x, a - 1);
}
int create(struct stack *x)
{
x->TowerTop = -1;
}
int full(const struct stack *x)
{
if (x->TowerTop == SIZE-1)
{
return 1;
}
else
{
return 0;
}
}
void push(int Elem, struct stack *x)
{
if (full(x))
{
printf("Stack is full");
}
else
{
x->TowerTop++;
x->Elem[x->TowerTop] = Elem;
}
}
void pop(struct stack *x)
{
if (x->TowerTop == -1)
{
printf("Empty");
}
else
{
x->TowerTop--;
}
}
請不,我沒有改變任何邏輯或類型或任何增加的空間。
第二步:讀取代碼。
其實我可能會在稍後再回來,但我快速閱讀,有一些基本的東西需要說。 main
函數應始終返回int
。根據C標準,只能用兩種方式聲明main
函數:int main(void)
(不帶參數)或int main(int argc, char *argv[]);
(帶命令行參數)。
然後,您必須知道,兩個變量a
和j
是全局文件。這意味着你可以在同一個源文件中的任何地方訪問它們。聽起來不錯,不起作用。除非您沒有其他選擇(例如使用sigaction
),否則您應該永遠不要做全局變量。在你的情況下,他們真的不需要。
最後,評論。請讚揚你的代碼。雖然大部分內容在這裏很容易理解,但函數lolol
(該名稱根本沒有意義)正在做一些我在快速查看代碼時無法理解的內容。
第三步:在編譯
gcc file.c
=> 4警告。除非你知道自己在做什麼,並且是一位經驗豐富的C程序員 - 你還沒有(當然),編譯時不應該有任何警告。此外,您應該使用-Wall -Wextra
開關進行編譯。這將會拋出更多的警告,但可以讓你在錯誤發生之前就發現它們。
因此,我們將修復警告:
warning: return type of ‘main’ is not ‘int’ [-Wmain]
。好的,讓我們切換。正如我前面所說,void main()
變成int main(void)
。
file.c:64:34: warning: passing argument 2 of ‘push’ makes pointer from integer without a cast [-Wint-conversion]
=>好的,在這裏您使用push
函數,我假設你寫了。但是,當您傳遞int
時,此功能需要第一個參數int
和struct stack *
,因爲它的第二個參數是 。讓我們來修正:push(x->Elem[x->TowerTop], x2->Elem[x2->TowerTop]);
變成push(x->Elem[x->TowerTop], x2);
,因爲您要將x->Elem[x->TowerTop]
推到x2
堆棧的頂部。
- 在未來三年的警告同樣的事情,作爲
pop
線66,push
線70和pop
線72
- 接下來兩個警告是相同的:
file.c:74:1: warning: control reaches end of non-void function [-Wreturn-type]
=>我仍然不知道什麼是lolol
這意味着要做,所以我只需在其末尾添加一個return 0
,並將create
函數切換爲void
類型。
下面是更正後的代碼:
#include <stdio.h>
#define SIZE 64
struct stack
{
int TowerTop;
int Elem[SIZE];
};
void push(int Elem, struct stack *x);
void pop(struct stack *x);
void create (struct stack *x);
int full(const struct stack *x);
int lolol(struct stack *x, struct stack *x2, struct stack *x3, int a);
int a;
int j;
int main(void)
{
//scanf("%d", &a);
a = 5;
struct stack Tower1;
struct stack Tower2;
struct stack Tower3;
create(&Tower1);
create(&Tower2);
create(&Tower3);
for (int i = 0; i <= SIZE - 1; i++)
{
Tower1.Elem[i] = 0;
Tower2.Elem[i] = 0;
Tower3.Elem[i] = 0;
}
for (int i = 0; i <= a; i++)
{
Tower1.Elem[i] = i + 1;
}
for (int i = 0; i < a; i++)
{
printf("%d %7d %7d\n", Tower1.Elem[i], Tower2.Elem[i], Tower3.Elem[i]);
}
lolol(&Tower1, &Tower2, &Tower3, a);
printf("%d\n", j);
for (int i = 0; i < a; i++)
{
printf("%d %7d %7d\n", Tower1.Elem[i], Tower2.Elem[i], Tower3.Elem[i]);
}
}
int lolol(struct stack *x, struct stack *x2, struct stack *x3, int a)
{
if (a == 1)
{
printf("\n Disk 1 move to");
push(x->Elem[x->TowerTop], x2);
j++;
pop(x);
return 0;
}
lolol(x, x3, x2, a - 1);
push(x->Elem[x->TowerTop], x2);
j++;
pop(x);
lolol(x3, x2, x, a - 1);
return 0;
}
void create(struct stack *x)
{
x->TowerTop = -1;
}
int full(const struct stack *x)
{
if (x->TowerTop == SIZE-1)
{
return 1;
}
else
{
return 0;
}
}
void push(int Elem, struct stack *x)
{
if (full(x))
{
printf("Stack is full");
}
else
{
x->TowerTop++;
x->Elem[x->TowerTop] = Elem;
}
}
void pop(struct stack *x)
{
if (x->TowerTop == -1)
{
printf("Empty");
}
else
{
x->TowerTop--;
}
}
編譯並沒有SIGSEGV運行。
最後一步:進一步說
我將談論的話題更先進,但它可能是對你有用。首先,獲取有關堆棧的更多信息以及它們如何工作,因爲我不確定您是否完全理解它。
此外,要調試您的程序,您可以使用valgrind
,它是一個內存檢查器工具,非常有用,並且總是很方便。要使用它,在編譯時添加標誌-g
。
我建議看看gdb
以及GNU Linux調試器。很強大。
功能full
可以更改爲簡單return x->TowerTop == SIZE - 1
。它避免了分支,因此運行速度會更快。
這就是所有人。仍然不確定你的代碼應該做什麼,但你只問如何解決你的段錯誤。現在請記住。 編譯時不要發出任何警告。
謝謝。
你做了什麼調試?你是否查找了導致Segfault的原因? – Carcigenicate
尼斯縮進。 – tkausl
學習[問]並提供[mcve]。注:作業題目有額外的要求,要成爲話題。你的老師希望你自己解決它。編程包括調試。習慣它。 – Olaf