簡體   English   中英

用於在整數數組中查找最小值的程序(在 C 中)將無法編譯

[英]program for finding the minimum value in an array of integersi(in C) won't compile

我試圖想出一個程序,它從命令行讀取數字,將 argv 數組轉換為整數,然后在這些整數的數組中找到最小的整數。 下面是我的這個程序的代碼,有人可以幫我嗎?

#include <stdio.h>
#include <stdlib.h>
int *integerizeArgs(int, char **);
int *findMin(int, int *);

int *integerizeArgs(int argc, char **argv)
{
        int i = 0;
        int *a = malloc(sizeof(int) * (argc-1));
        for(i= 1; i < argc; ++i){
                a[i-1] = atoi(argv[1]);
                return a;
        }
return 0;
}


int *findMin(int itemCount, int *a) {
        int i, smallest = a[0];
        for (i=0; i < itemCount; i++) {
                if(a[i] < smallest) {
                        smallest = a[i];
                        return smallest;
                        }
                return 0;
        }
        return 0;
}

int main(int argc, char **argv){
        int *a = integerizeArgs(argc, argv);
        int b = findMin(argc, a[0]);
        printf("%d", b);
        return 0;
}

編寫適當的代碼。

  • 您應該檢查malloc()是否成功。
  • 小心打字錯誤。 argv[1]不像這里的argv[i]合理。
  • 不要使用return; 當您不想從函數返回時。
  • 使用正確的類型。 區分“正常”整數和指針。
  • 小心一對一的錯誤 在這種情況下,分配的是argc-1元素,而不是argc元素。
  • 你應該釋放你分配的任何東西。

更正的代碼:

#include <stdio.h>
#include <stdlib.h>
int *integerizeArgs(int, char **);
int findMin(int, int *);

int *integerizeArgs(int argc, char **argv)
{
        int i = 0;
        int *a = malloc(sizeof(int) * (argc-1));
        if (a == NULL){ /* add error check */
                perror("malloc");
                exit(1);
        }
        for(i= 1; i < argc; ++i){
                a[i-1] = atoi(argv[i]); /* convert each arguments instead of only the first one */
                /* don't return when the process is not done */
        }
        return a; /* return the result */
}

/* use proper return type */
int findMin(int itemCount, int *a) {
        int i, smallest = a[0];
        for (i=0; i < itemCount; i++) {
                if(a[i] < smallest) {
                        smallest = a[i];
                        /* don't return when the process is not done */
                }
                /* don't return when the process is not done */
        }
        return smallest; /* return the result */
}

int main(int argc, char **argv){
        int *a = integerizeArgs(argc, argv);
        /* pass the (pointer to) the array instead of the first element of the array (&a[0] is also OK) */
        /* pass correct itemCount (there are argc-1 items because the first argument typically is the command) */
        int b = findMin(argc - 1, a);
        printf("%d", b);
        free(a); /* free whatever you allocated */
        return 0;
}

此代碼存在多個問題。 如此重大的誤解往往會導致您的資源對您不起作用。 您是否考慮過嘗試其他資源?

如果您還不了解過程式編程的基礎知識,我建議您先學習一門不同的語言。 不幸的是,我還沒有遇到一本像樣的 C 編程書,它既教授一般的過程編程又教授 C 編程。 我所知道的唯一書籍似乎要求您已經了解過程編程。 我會嘗試在這篇文章中對此提供一些幫助。

我強烈推薦 K&R 2E,前提是你已經了解了過程編程的基礎知識; 記住在遇到練習時做練習,因為它們是學習經驗的重要組成部分。


您似乎對returnforif對執行流程的影響感到非常困惑。 例如,C 是一種過程語言,這意味着它的結構類似於食譜中的食譜(過程)。

好吧,這太簡單了,但是如果您想到“將烤箱預熱到 180C(在第 42 頁中描述)”和“將洋蔥焦糖化”之類的步驟,就好像它們是單獨的程序一樣,那么我們可以建立像return這樣的關鍵字的用法, for and if ,請耐心for

當您翻到第 42 頁時,您可能會注意到該過程很簡單,但與食譜相去甚遠,如下所示:

  • 確保烤箱是空的,如有必要,在其中一個架子的前面安裝烤箱溫度計。
  • if烤箱是燃氣烤箱:
    • 點火柴。
    • 跪在烤箱前,將旋鈕調到合適的溫度。
    • 將點燃的火柴與氣流接觸,讓您的手指始終遠離氣流。
  • else將旋鈕轉到合適的溫度。
  • 關閉烤箱。
  • for持續時間開始當您關閉烤箱,當溫度計達到適當的值結束,要定期檢查溫度計
  • return上一個程序。

在這里, ifelse顯然是為了確保您為烤箱選擇合適的路徑。 您的計算機也是如此。 您告訴它根據代碼中的條件選擇哪一條路徑。

return關鍵字用於告訴您程序已經結束,您應該恢復之前使用的程序。

程序中也嵌入了一個循環。 這可以用for語言來表達,即“從關閉烤箱開始到溫度計達到適當值結束的持續時間,定期檢查溫度計”將大致翻譯為:

close(oven);
for (actual_temp = check_temp(oven); actual_temp < desired_temp; actual_temp = check_temp(oven)) {
    sleep(15 minutes);
}

食譜很容易理解,因為它們是用自然語言編寫的。 然而,計算機程序不是。 編程語言具有在自然語言中不太常用的習語,例如變量范圍和內存位置,因此始終如一地使用這些習語很重要。

我建議設計軟件,就好像它是為了適應環境一樣。 我可以看到您已經通過將argcargv (或其翻譯后的等效項)轉發到您的每個函數中給出了一些想法,但是需要對環境進行更深入的分析。

它違背了函數執行分配並期望調用者為該分配執行清理的原則。 如果分析 C 標准庫設置的示例,分配內存的函數只有分配函數、線程​​創建和文件創建。 其他一切都讓調用者選擇如何分配內存。 因此,您的integerizeArgs函數可能應該重構:

int *integerize_arguments(int *destination, char **source, size_t length) {
    for (size_t x = 0; x < length; x++) {
        if (sscanf(source[x], "%d", &destination[x]) != 1) {
            return NULL;
        }
    }
    return destination;
}

例如,您是否注意到它與memcpy相似程度? 使用這種模式,調用者可以選擇數組應該具有什么樣的分配,如果您決定不需要malloc ,這對於維護來說非常好。

還要注意我如何將size_t用於索引變量。 這很重要,因為允許數組為負數通常沒有意義。


至於你的findMin函數,我能給出的最好建議是考慮我們之前討論過的程序語言。 我不認為您給計算機的指令與您腦中的指令相同。 如果是,則它們沒有意義,您可能需要手動執行該過程幾次以查看出了什么問題。

  • 除非調用者(在本例中是main )需要知道最小值的地址, findMin不需要返回int * 它應該返回int 另一方面,如果main需要知道最小值的位置,那么您的算法需要進行調整,因為您當前沒有在邏輯中存儲該位置。
  • 正如 MikeCAT 所涵蓋的那樣,在檢查了整個數組之前,您不應return到之前的過程。 因此你的return smallest; 應該低於for循環。

這篇文章越來越長,有點變成了自己的書……所以我會在這里結束,總結一下,建議您購買一本關於編程的書。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM