編程學習過程中,我曾經我犯過一個錯誤(我想多數人也跟我一樣心急)。“學”完C語言后緊接著學C++,等稍微有基礎了之后開始接觸C++ GUI Qt編程等。但學習Qt圖形化編程的過程中又發現寫程序的關鍵點無外乎編寫函數或方法。自己對函數編寫的理解不太深入而導致不會寫“自己”的C/C++函數(或方法)。雖然我們能夠將需求分解成多個模塊或函數,但這并不意味著我們也能將需求編寫成函數(或方法)來讓程序正常運行。因此,本文簡要總結一下有關函數的一些概念及個人學習體會。
圖1 人腦將概念分解成“屬性”和“函數”的過程
1、內存中用一維空間來表示多維世界
也許我們活在一維世界里,只是我們認為這個世界是三維(3D)或更多維的復雜多樣。 為什么這么說呢?因為計算機的世界就是由一維數組升級成多維數組形式給我們演變出了多維畫面和模型。比如,內存存最小地址標識單位為字節(byte),然后我們將一維內存通過多維形式標識并在此基礎上借助數組、指針、結構體等數據結構構造了更復雜的模型和需求,最終能夠在內存的一維空間中完成多維現實世界的“模擬”需求。如下圖2所示一維數組多種標識方法就是其中的具體案例之一。計算機內存其實一維的,一維空間來表示多維空間是我們不可否認的事實。
圖2 內存中一維數組來表示多維數組
2、為什編寫函數是程序員的基本功
雖然我們通過一維內存空間來表示出多維現實世界,但其現實過程需要較理解不同數據類型及其在內存中的布局、程序的運行原理、內存中多種數據結構的融融應用等基礎概念及原理。我之前對編程感到恐怖,因為看到那些代碼時腦袋的形成的形象是空白的(或者說一維的),腦海里沒有形成這些代碼在磁盤、內存、寄存器、CPU等之間“流”進“流”的過程和狀態。
在這樣的狀態下,我們無論學C或面向對象的C++及Qt等其他編程語言及工具,最終編寫函數或對象的方法的過程中總會感覺到無從下手。我想這也是我們覺得C/C++難學原因之一,因此我回頭重學了C語言的基礎知識。在這個過程中,兩個內容的回顧對我帶來了意想不到的收獲。其中之一是C語言面向對象編程,尤其是用C語言實現封裝和繼承特性。其二是用C語句描述算法的相關解釋說明。
圖3 程序在內存中布局
3、用C語句描述算法
程序就是對計算機要執行的一組操作序列的描述。高級語言源程序的基本組成單位是語句。語句按功能可以分為兩類: 一類用于描述計算機要執行的操作運算(如賦值語句),另一類是控制上述操作運算的執行順序(如循環控制語句) 。前一類稱為操作運算語句,后一類稱為流程控制語句。
C語言是一種表達式語言,所有的操作運算都通過表達式來實現。由表達式組成的語句稱為表達式語句,它由一個表達式后接一個分號組成(注意,沒有分號的不是語句)。表達式語句可以分為以下三種基本類型:
(1) 賦值語句:由賦值表達式加一個分號組成。例如:i=1;
(2) 函數調用語句:
(3) 空語句
高級語言一般以兩種形式提供流程控制:
(1)形成流程控制結構(如if、while、for語句)。
(2)簡單的流程轉向。
控制結構分為順序、選擇和循環等三種基本結構,大多數高級語言都提供這三種控制結構。準確地說,是后兩種。因為順序型是自然形成的,無須在程序中加以專門的控制。
圖4 if或switch語句模擬多路選擇結構的開關電路
限定轉向語句(簡單的流程轉向)不形成控制結構,只是簡單地使流程從其所在處轉向另一處。但是它不允許用戶自己指定轉向,而是按系統事先規定的原則向某一點轉移,用戶不必指定轉向。C語言中屬于這類的語句有三種:
(1) break 語句:它的功能是把流程從所在處轉向所在的循環結構或多路選擇結構之后,或者說是中止執行這些結構(見圖5)。
(2) continue 語句:使本次循環體的執行提前結束(不再執行continue下面的語句),然后再根據循環條件是否滿足,決定是否進入下次循環(見圖5)。
圖5 限定轉向語句(簡單的流程轉向)
(3) 函數調用和返回: 函數調用的功能是使流程轉向所調用的函數體。return語句的功能是使流程從被調用函數返回主調函數。這兩種流程控制都可能伴隨有參數傳遞。
綜前所述,函數編寫的關鍵在理解和善用操作語句(賦值語句)和控制語句,把C語言中的基本語句歸納如下:
圖6 C語言中的基本語句
4、理解指針(地址)和結構體
指針是一個特殊的變量,它里面存儲的數值被解釋成為內存里的一個地址。要搞清一個指針需要搞清指針的四方面的內容:指針的類型、指針所指向的類型、指針的值或者叫指針所指向的內存區、指針本身所占據的內存區。
結構體是構造復雜數據類型的最有效的工具,對這個概念還不了解,基本上無法構造數據模型,一般能日常使用的程序中沒有一個業務體是完全使用原生數據類型來完成的,如下圖6所示。設計數據模型的時候,一般先把頭文件中的結構體數據整理出來。然后設計好功能函數的參數,以及名字,然后才真正開始寫C源碼。
圖7 用C語言來封裝屬性和函數
其實C語言也能編寫面向對象編程風格的程序,如附件1所示的封裝特性演示代碼就采用封裝特性 ,還有繼承特性的實現,篇幅原因不再贅述。當看懂了這段代碼后,我突然明白了函數指針、結構體、面向對象編程中的this(或self),及構造函數等等的來歷。也領悟到了將函數封裝到的類(class或對象)里之后,通過點或指針訪問函數(方法)來實現對結構體成員訪問和修改在內存中的實現過程。
5、結束語
函數、指針、結構體這三大塊硬骨頭是學習C語言(或編程)的絆腳石 ,下功夫拿掉基本上C語言的大動脈就打通了,如果想開發實際能用到的程序,那么也需要了解 文件和數據庫的讀寫等第四塊常被我們忽視的骨頭。 尤其是每當通過new來創建對象或定義結構體變量來創建數據模型時,我們會感覺到計算機世界里創建資源和使用資源時多么“簡單”和“直接”的。如果在現實世界,從0到1的價值創造(不是資源調配)是多么難的事情,需要我們要么用金錢換來或其他方式對等交換。因此,雖然編程很“難”(與其說難、不如說我們貪),但相對于現實世界的種種困難,讓我們在計算機虛擬世界里擁有無限的資源和可能性。
圖8 電腦對“程序”的理解和處理過程
參考資料:
C語言程序設計教程 譚浩強 張基溫 唐永炎 高等教育出版社
C語言游戲實戰教程
附件1:C語言封裝特性演示代碼
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
struct student {
void (*setStudentId)(struct student* s, int year, int classNum, int serialNum);
const char* (*getGender)(struct student* s);
void (*setGender)(struct student* s, const char* strGender);
int id; // 學號
char name[20]; // 姓名
int gender; // 性別
int mark; // 分數
};
void setStudentId(struct student* s, int year, int classNum, int serialNum)
{
char buffer[20];
sprintf(buffer, "%d%d%d", year, classNum, serialNum);
int id = atoi(buffer);
s->id = id;
}
const char* getGender(struct student* s)
{
if (s->gender == 0)
{
return "女";
}
else if (s->gender == 1)
{
return "男";
}
return "未知";
}
void setGender(struct student* s, const char* strGender)
{
int numGender;
if (strcmp("男", strGender) == 0)
{
numGender = 1;
}
else if (strcmp("女", strGender) == 0)
{
numGender = 0;
}
else
{
numGender = -1;
}
s->gender = numGender;
}
void initStudent(struct student* s)
{
s->setStudentId = setStudentId;
s->getGender = getGender;
s->setGender = setGender;
}
int main()
{
struct student stu;
// 初始化student
initStudent(&stu);
// 學號:202212326
// 姓名:小明
// 性別: 男
// 分數:98
stu.setStudentId(&stu, 2022, 123, 26);
strcpy(stu.name, "小明");
stu.setGender(&stu, "男");
stu.mark = 98;
// 打印這些數值
printf("學號:%d\\n", stu.id);
printf("姓名:%s\\n", stu.name);
const char* gender = stu.getGender(&stu);
printf("性別:%s\\n", gender);
printf("分數:%d\\n", stu.mark);
return 0;
}
收錄于合集 **#**軟件工程
9個
-
計算機
+關注
關注
19文章
7525瀏覽量
88328 -
內存
+關注
關注
8文章
3042瀏覽量
74179 -
模型
+關注
關注
1文章
3279瀏覽量
48976
發布評論請先 登錄
相關推薦
評論