编程学习过程中,我曾经我犯过一个错误(我想多数人也跟我一样心急)。“学”完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文章
7488浏览量
87852 -
内存
+关注
关注
8文章
3019浏览量
74005 -
模型
+关注
关注
1文章
3226浏览量
48809
发布评论请先 登录
相关推荐
评论