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

相关文章

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

C语言中的数据类型强制转换

《C语言中的数据类型强制转换》:本文主要介绍C语言中的数据类型强制转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C语言数据类型强制转换自动转换强制转换类型总结C语言数据类型强制转换强制类型转换:是通过类型转换运算来实现的,主要的数据类型转换分为自动转换

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

C语言实现两个变量值交换的三种方式

《C语言实现两个变量值交换的三种方式》两个变量值的交换是编程中最常见的问题之一,以下将介绍三种变量的交换方式,其中第一种方式是最常用也是最实用的,后两种方式一般只在特殊限制下使用,需要的朋友可以参考下... 目录1.使用临时变量(推荐)2.相加和相减的方式(值较大时可能丢失数据)3.按位异或运算1.使用临时

使用C语言实现交换整数的奇数位和偶数位

《使用C语言实现交换整数的奇数位和偶数位》在C语言中,要交换一个整数的二进制位中的奇数位和偶数位,重点需要理解位操作,当我们谈论二进制位的奇数位和偶数位时,我们是指从右到左数的位置,本文给大家介绍了使... 目录一、问题描述二、解决思路三、函数实现四、宏实现五、总结一、问题描述使用C语言代码实现:将一个整

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

Go语言中最便捷的http请求包resty的使用详解

《Go语言中最便捷的http请求包resty的使用详解》go语言虽然自身就有net/http包,但是说实话用起来没那么好用,resty包是go语言中一个非常受欢迎的http请求处理包,下面我们一起来学... 目录安装一、一个简单的get二、带查询参数三、设置请求头、body四、设置表单数据五、处理响应六、超

C语言中的浮点数存储详解

《C语言中的浮点数存储详解》:本文主要介绍C语言中的浮点数存储详解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、首先明确一个概念2、接下来,讲解C语言中浮点型数存储的规则2.1、可以将上述公式分为两部分来看2.2、问:十进制小数0.5该如何存储?2.3 浮点

Python FastAPI入门安装使用

《PythonFastAPI入门安装使用》FastAPI是一个现代、快速的PythonWeb框架,用于构建API,它基于Python3.6+的类型提示特性,使得代码更加简洁且易于绶护,这篇文章主要介... 目录第一节:FastAPI入门一、FastAPI框架介绍什么是ASGI服务(WSGI)二、FastAP

基于Python实现多语言朗读与单词选择测验

《基于Python实现多语言朗读与单词选择测验》在数字化教育日益普及的今天,开发一款能够支持多语言朗读和单词选择测验的程序,对于语言学习者来说无疑是一个巨大的福音,下面我们就来用Python实现一个这... 目录一、项目概述二、环境准备三、实现朗读功能四、实现单词选择测验五、创建图形用户界面六、运行程序七、