我有一些相對初學編程的人想說的話,寫在這里,希望可以給有緣看到這些內容的入門級編程人員一些幫助。
C語言難嗎?
第一個問題,C語言難嗎?或者說編程難嗎?在目前的環境里,第一次接觸 C 語言的人應該大多數都是大學生了。你們大部分人已經經歷過中國的高考,而且大部分人都在高考中取得了不錯的成績,說實話,編程比起很多高中的課程都簡單,舉兩個真實的例子:
比爾·蓋茨出生於1955年,但是他在1971年,已經開始為湖畔中學編寫程序,其中包括一款課表安排軟件【來源百度百科】。大家可以算一下,他在 1971 年應該是 16 歲。另一個人就更厲害了,來自芬蘭的 Linus,也是在高中的時候就寫出了 Linux 操作系統最初的版本。(Android 可以說就是 Linux 在手機上的一個分支)
雖然這兩個人都是天才,我們可能沒辦法和他們比,但是仔細想想你們現在做的題,題目中要解決的問題真的很難嗎?
寫代碼的一般步驟
今天以群里一個小伙伴的題目,講一下寫代碼的一般步驟,我把題目內容摘抄在這里:
“鍵盤輸入一個3行4列的整型二維數組a[3][4]的數據,找到鞍點。所謂鞍點,就是該位置上的數,在它所在行最大(沒有跟它相等的數),在它所在列最小(沒有跟它相等的數)。注意:也可能沒有鞍點。若沒有鞍點,輸出:“not exist””
這道題涉及到了多位數組,有些同學就有點害怕了,但是如果拋開寫代碼,假如你自己就是一個程序,如果別人給你一個二維數組,你能從中找出鞍點嗎?我相信大部分人都是可以吧?甚至於找個小學四五年級的學生,只要你把什么是鞍點給他解釋清楚,他也能給你找出給定數字中的鞍點。
假如你自己就是一個程序,說點題外話,我這樣說是希望你們可以設身處地的站在計算機的角度考慮問題,舉個簡單的例子,比如
scanf("%d,%d", &a, &b);
這句代碼,里面的“%d,%d”被稱為格式化字符串,就是計算機希望你在輸入的時候以這種格式輸入,比如這個地方的格式就是兩個數之間有個逗號,所以輸入a和b的值時,最好是輸入“3,4”這樣的。
看到一個題目,首先要做的事就是想思路,而不是直接寫代碼。比如我看到這道題,我腦海里出現的思路是這樣的:
- 找到第一行最大的數,看一下它是不是在所在列最小。
- 找到第二行最大的數,看一下它是不是在所在列最小。
- 找到第三行最大的數,看一下它是不是在所在列最小。
當然了,因為每個人思考問題的方式不一樣,所以每個人的思路也是不一樣的,這也就導致我們每個人寫出來的代碼也會不一樣,所以編程的題目是沒有標准答案的。
想思路是寫代碼最重要的步驟,如果沒有思路,肯定寫不出代碼。比如這道題的這個思路,相信大部分人都能想出來,但是就是寫不出來是不是?這就是另一項能力,把自己的思路轉換成代碼的能力,這項能力沒有捷徑,只能通過多寫多練來達成。最怕的就是眼高手低,覺得自己有思路,代碼就不寫了。另外,多思考也是非常重要的,腦子這個東西一定要多用,不要一遇到問題就在群里問,說不定自己離成功就差一點點了。
編寫代碼
接下來就是把我們的思路寫成代碼,說難也難,說不難也不難。
#include <stdio.h>
int main()
{
// 為了可讀性,這里定義了變量 line 和 column 代表數和列數。
int lineCount = 3, columnCount = 4;
// 定義數組
int array[lineCount][columnCount];
// 輸入二維數組的值
for (int line = 0; line < lineCount; ++line)
{
for (int column = 0; column < columnCount; ++column)
{
scanf("%d", &array[line][column]);
}
}
// 定義一個變量存儲是否存在鞍點
int exist = 0;
// 一行一行的查找鞍點
for (int line = 0; line < lineCount; ++line)
{
// 定義一個變量代表一行中最大值所在列
int maxCol = 0;
// 定義一個變量代表這行是否存在不止一個最大值
int hasEqualInLine = 0;
// 循環一個行中的數,找出其中的最大值
for (int col = 1; col < columnCount; ++col)
{
if (array[line][col] > array[line][maxCol])
{
// 這個條件成立,說明在這一行中找到一個更大的數字
maxCol = col;
hasEqualInLine = 0;
}
else if (array[line][col] == array[line][maxCol])
{
// 又找到一個數和當前的最大值相等
hasEqualInLine = 1;
}
}
// 程序走到這里就是循環完一行了,這個時候就可以判斷當前行存不存在鞍點了
if (!hasEqualInLine)
{
// 這個變量表示這個數在所在列是否是最小數
int isMin = 1;
// 定義一個變量代表所在列是否有相等值
int hasEqualInColumn = 0;
for (int line2 = 0; line2 < lineCount; ++line2)
{
if (line2 == line) {
// 沒必要和這個數自身比
continue;
}
if (array[line2][maxCol] < array[line][maxCol])
{
// 此列中其他行中的數比我們找到的數小
isMin = 0;
break;
}
else if (array[line2][maxCol] == array[line][maxCol])
{
// 此列中其他行存在和我們找到的數相等的數
hasEqualInColumn = 1;
break;
}
}
if (isMin && !hasEqualInColumn)
{
// 這個數是鞍點
exist = 1;
printf("a[%d][%d]=%d\n", line, maxCol, array[line][maxCol]);
}
}
}
if (!exist)
{
// 程序執行到最后都沒有找到鞍點
printf("not exist\n");
}
}
這就是我按照我的思路寫出來的代碼,在寫這個代碼之前,我也沒想到能寫這么多行,為了保證已讀性,里面加了很多注釋,大家可以讀一下,驗證一下。
寫在最后
如果想學好 C 語言,學校發的教科書起碼要看一遍,看一遍書基本上語法就都掌握了。有一些問問題的人連 switch 語句怎么寫都不知道就來問怎么改,遇到這樣的人真是不知道該從何教起。另外就是在問問題前可以先嘗試在網上查一下有沒有現成的解決方案,畢竟每個人的時間都是寶貴的,我希望每個問問題的人都是在經過自己本人嘗試過無果再問問題,而不是自己懶得去想懶得去做就來問別人,沒有人有義務來幫你去思考。