c程序语言设定定义域,高观点下的C语言入门

2023-10-20 20:10

本文主要是介绍c程序语言设定定义域,高观点下的C语言入门,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C语言,是大多数科班出身的程序员的第一门语言,也是大多数底层技术爱好者的主要语言。

在计算机领域,底层技术就是核心技术。

C语言刚入门时,其实还是很别扭的,因为它的设计与高中数学教育形成的思维惯式不太一样。

1,相等==和赋值=的区分,

在数学里,一般不需要特别的符号来区分相等和赋值,人们可以根据上下文的语义知道表示的是什么。

x=1的同时也就暗含了x==1,在给人看时不需要特意说明这点。

但在电脑程序里需要区分,因为电脑的理解力比人差得多,也就需要在程序设计时添加更多的细节。

比较x是否等于1,和让x等于1,是两种不同的运算。

必须给电脑明确指出,它才能正确运行。

因此,我们需要两个“不同但又类似”的符号,作为这两个关联场景的运算符,C语言选择了=用于赋值,==用于相等。

不等,则使用了!=,因为ascii码里没有数学上那个不等号,如果使用ascii码之外的符号就会需要额外的输入法软件,这对编程语言是不可接受的。

没有哪个程序员在编程时想切换输入法,除非它要输入非英文字符串。

之所以不让==表示赋值,而让=继续符合人们中学时学的通常语义,是因为赋值比相等在程序里出现的次数更多。

比较运算可以是>、>=、 < 、<= 、!= 、!,==出现的次数其实不多。

但赋值,包含扩展的+=、-=之类的,出现的次数特别多,可以少打一个符号。

对使用频率高的词汇使用较短的编码,是所有语言的惯例。也是符合“信息论”的编码原则的。

“我”,在汉语里的笔画算比较少的,而且结构很醒目。

英语则是I,法语是Je,这种高频次的第一人称代词,一般都是简短+单音节+元音结尾的词。

第三人称的“是”,也是另一个高频词汇,英语是is,法语是est,例如多邻国的名句:C’est une fille anglaise.

汉语是典型分析语,语义表达不依赖动词形式变化,所有人称的“是”都一样,但这个字也笔画简单而结构显眼。

书法好的可以把它写地龙飞凤舞,大气磅礴。

回到C语言,另外,如果赋值使用了==,那么频次不低的+=就变成了+==,三个字符不但会给词法解析带来额外负担,还会让程序员多打一个字符:(

程序员都是懒人,否则他们就不会把重复的活儿给电脑做了:(

+=在循环语句里用于变量的自增,使用频率仅低于++。

2,从0开始计数,

这也是很不符合惯例的设计。

人们数数是从1开始,0在数学史上出现也是较晚的,比1晚的多。

但是在二维数组中,如果从1开始计数,那么2行16列的数组,16是第1行最后1个元素,17是第2行第1个元素。

可是,16/16=1余0,17/16=1余1,它们的数组索引与它们与数组大小的除法结果就不一致了:

“商+1”才是行号,但余数是0时商又不需要+1,这在编程时会额外消耗程序员的脑力,而且这种计算细节很容易出错。

另外,就是索引值与元素在数组中的实际偏移量不一致。

第1个元素与数组首地址的偏移量是0,而不是1,&a[1]对应的是a+1 - 1 = a+0。

就跟公元1世纪不是1xx年,而是xx年一样,算起来别扭又烧脑。

如果让索引号和偏移量一致,那么0号位的内存就浪费了。

这在内存稀缺的上世纪70年代,是不可接受的。

最后,为了让数组索引与除法/和模运算%的结果一致,就从0开始计数了。

模运算%的结果一致叫做“同余”,线性同余方程组的求解,最早可以追溯到中国古代数学著作“孙子算经”。

宋代大数学家秦九韶在“数学九章”中把这个解法叫做“大衍求一术”,现代的抽象代数里叫做“中国剩余定理”。

秦九韶的解法,同时也是这个定理的“构造性证明”。

构造性证明,比存在性和唯一性的证明要牛,因为它同时给出了求解步骤。

中国古代在代数学领域还是很牛的:(

几何学上可能古希腊牛一些,毕竟欧几里德比较牛,“几何原本”,“古希腊三大难题”。

但古希腊三大“几何”难题,最后都是靠“代数”否决的:(

3,变量,

变量的出现伴随着方程的诞生,可以追溯到一元一次方程的出现,久得估计没法考证了。

秦九韶解线性同余方程组的中国剩余定理,肯定比这个晚了至少上千年。

方程确定的是隐函数,函数确定的自然是显函数。

4,函数,

C语言的函数和数学上的函数有点区别,它是一个处理某个功能的代码模块,可以被另一个函数调用。

它也和数学上的函数一样有参数(自变量),也有返回值(结果),这可能是它也叫做函数的原因。

它也是从参数空间(定义域)到返回值空间(值域)的一一映射:在代码没有BUG的情况下同样的参数该算出同样的结果来。

调用时需要传参数,参数和返回值在不需要的时候也可以没有,void f()这种。

整个程序的入口函数就是main函数,它被操作系统加载程序时调用,Linux的这个API是execve()。

5,指针,

指针,是C语言的压轴章节。

这章之后,就是文件读写的API了,严格来说不属于编程语言范畴,而是属于IO库的范畴。

“去书架上把C primer plus借来”。

书架就是“指针”,是C primer plus这本书存放的位置。

C primer plus就是指针的内容,即书架上存的是什么。

内存就是计算机的“书架”,内存里的值就是这个“书架”上的“书”。

对于电脑来说要尽量细化,所以给内存按字节编号,指针就是这类编号。

还可以给书里的章节编号,那么书架就是二级指针,书是一级指针,章节是指针的内容。

地址,在日常生活中也是常见的。

寄快递需要有地址和收货人,去某地址找某个收货人,把快件交给他之后,他的总体重量增加了1公斤,就是*p += 1。

6,递归,

递归,就是利用“函数栈”保存上下文状态的迭代。

递归比迭代难理解,但在编程上比迭代容易实现,因为它不需要手动保存上下文状态。

按照数学归纳法,当k = 0的时候条件成立,当k = n的时候也成立,当k=n+1的时候也成立,计算k = 10的结果。

从k=0开始,根据迭代公式,一直迭代到k=10,每一步都要保存k跌代到哪里了,结果是什么。

k和结果就是上下文,手动管理它们的存放就是迭代,把它们写在函数参数里,让程序在函数调用的过程里自动管理,就是递归。

参数,也是函数的局部变量,局部变量的管理由编译器实现,实际上简化了程序员的工作难度。

二叉树遍历时,开一个动态数组,不断把遍历到的节点按遍历顺序存进去,同时记录哪个分支遍历过了,哪个分支没有遍历,迭代到哪里了,实际是比较麻烦的。

但是,用函数栈来存储状态,就只需要改变每次迭代的参数就可以了,代码就简单得多。

递归难理解,可能在于它是反向迭代,大多数场景下的都是从10跌代到0,截至条件与日常经验是反过来的。

倒着数数,相对比较别扭。

7,字符和字节,

单字节并不足以表示全球主要语言的所有常用字符,char作为1个字节的变量同时表示字符,是ascii码时代的遗迹。

那个时候字符和字节的语义是一致的。

unicode的出现比较晚,所以C后来又添加了wchar类型,但char已经在各种代码里用惯了。

char既当字符变量,又当单字节变量,char*还作为缓冲区的指针,又当作字符串,差别只在于结尾0。

然后就有了著名的缓冲区溢出漏洞:(

不在字符串的string类型中记录长度,而是靠结尾的哨兵0,最后不得不搞出了各种snprintf函数。

每次strcpy、sprintf时都要在心里默算缓冲区够不够。

优点就是vsnprintf()函数的实现比较简单,因为字符和整数可以直接运算,

x % 10 + ‘0’就是数字要打印的字符。

char和char*字符串的使用,在C里是特别容易出BUG的地方。

本来,字符应该是无符号的,但是在char同时充当了有符号的单字节整数的情况下,就导致了char型的0x80在编译器扩展时成了负数。

unsigned char型的0x80是正的。

char在与int计算时需要注意它的最高位是0还是1,因为编译器会做符号扩展。

b23926a30f657f6b503a1dddc6dbf4fb.png

举报/反馈

这篇关于c程序语言设定定义域,高观点下的C语言入门的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/249456

相关文章

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成

Go语言使用Gin处理路由参数和查询参数

《Go语言使用Gin处理路由参数和查询参数》在WebAPI开发中,处理路由参数(PathParameter)和查询参数(QueryParameter)是非常常见的需求,下面我们就来看看Go语言... 目录一、路由参数 vs 查询参数二、Gin 获取路由参数和查询参数三、示例代码四、运行与测试1. 测试编程路

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

史上最全MybatisPlus从入门到精通

《史上最全MybatisPlus从入门到精通》MyBatis-Plus是MyBatis增强工具,简化开发并提升效率,支持自动映射表名/字段与实体类,提供条件构造器、多种查询方式(等值/范围/模糊/分页... 目录1.简介2.基础篇2.1.通用mapper接口操作2.2.通用service接口操作3.进阶篇3

Go语言网络故障诊断与调试技巧

《Go语言网络故障诊断与调试技巧》在分布式系统和微服务架构的浪潮中,网络编程成为系统性能和可靠性的核心支柱,从高并发的API服务到实时通信应用,网络的稳定性直接影响用户体验,本文面向熟悉Go基本语法和... 目录1. 引言2. Go 语言网络编程的优势与特色2.1 简洁高效的标准库2.2 强大的并发模型2.