高级语言程序设计
⭐⭐⭐课程网站⭐⭐⭐
HLP2022Fall - 2022年秋季学期《高级语言程序设计》 (ouc.ai)
▶ OUC在线课程中心:中国海洋大学 (ouc.edu.cn)
▶ OUC在线评测平台:222.195.147.104
关于课程:高级语言程序设计是面向大一学生开设的一门关于C语言学习和实践的课程。
关于我:我因为转专业,在选课的时候课程冲突了,被迫在大四来补上这门课。
关于网站:很多同学上课时遇到了很多问题,在微信群可以直接提问,老师和同学们都会为大家解答,我也会在微信群给大家解答,但很多问题需要重复答疑很多次,因此我汇总每周的问题,在网站中的该博文进行整理和解答,方便给大家答疑解惑,希望能帮助到大家。
$$
G_{total} = G_{OutClass} × 0.2 + G_{InClass} × 0.3 + G_{FinalExam} × 0.5 + G_{award} − G_{penalty} − G_{absence}
$$
对网站中我写的内容有疑惑或者建议的话,可以加我微信跟我说一下!
建议使用桌面端设备(宽屏设备)访问该网站,直接在浏览器中输入cosmicdusty.cc
即可访问!宽屏设备访问网站时,页面右侧会有导航栏
,点击可以直接跳转到对应位置。页面也有明亮
和暗黑
两种模式,可自行切换。
第一周 课堂事务
1 | 第一周 | 2022年09月08日周四 | 课堂事务;课程定位和主要内容;计算机的基本原理。 | 幻灯片 |
---|---|---|---|---|
L1 | 第一周 | 2022年09月08日周四 | 实验课一:熟悉Linux操作系统的基本操作。 | 实验手册 |
开发环境
郑老师和乔老师要求用了Linux系统,那我们就先按照老师说的做,在WSL/虚拟机/双系统/云服务器上做!
能不能在Windows上面用Dev和VS,要具体问一下老师。
目前用的系统是Linux的发行版Ubuntu 20.04,用这个的同学可能多一点,其他版本需要问一下老师。
环境的安装,下午和晚上讨论了很多了。可以翻翻微信群。遇到问题自己先尝试运用搜索引擎,看看能不能解答!!
以下都是针对Windows操作系统(大多数同学可能用的是Windows10/11)的,MacOS本身就是基于Unix的,这也是Linux的源头,所以,用MacOS的同学可以直接用终端就行了!
- 操作系统和编程语言的发展历史:Éric Lévénez’s site (levenez.com)
图灵
超算
The Unix-Haters Handbook
tiobe index
CoolShell
WSL
老师发了WSL的安装教程,建议先跟着做一遍,试试有没有问题!
请同学们尽量在今晚的实验课前配置好Linux系统环境,推荐安装比较流形的发行版本:Ubuntu。推荐使用windows自带的Microsoft store进行安装,具体可参考博客链接:Windows Microsoft Store安装Ubuntu_斯维因yin的博客-CSDN博客_微软商店ubuntu
如果实在安装不上或不习惯使用这种方式,可到本课程的BB平台上下载虚拟机文件和Ubuntu系统安装包,通过创建虚拟机,安装Ubuntu系统。
有能力的同学,可尝试安装双系统,但请注意系统引导菜单的修复,以及不要覆盖原系统所在的分区,该安装方式存在风险,请慎重操作。
windows store里安装Ubuntu以及遇到问题可参考:
Windows Microsoft Store安装Ubuntu_斯维因yin的博客-CSDN博客_微软商店安装ubuntuWslRegisterDistribution failed with error_ 0x8007019e、0x800701bc、0x80370102_奋斗的西瓜瓜的博客-CSDN博客
store里安装Ubuntu可能由于windows系统本身缺少一些组件或者系统设置未打开,导致安装过程中报错,可以参考:
WslRegisterDistribution failed with error_ 0x8007019e、0x800701bc、0x80370102_奋斗的西瓜瓜的博客-CSDN博客
Microsoft store下的ubuntu出现参考的对象类型不支持尝试的操作可以参考一下这个:
(仅临时解决办法)关于win10启动ubuntu报错_ShunDerhuang的博客-CSDN博客_win10ubuntu打不开
⭐win10启动ubuntu报错 参考的对象类型不支持尝试的操作_Chivalrous Expert的博客-CSDN博客_参考的对象类型不支持尝试的操作
Linux的安装我之前也粗略的写过(更多的是物理机上面Linux的安装),可参考:Linux安装记录|Murphy
虚拟机
我平时用虚拟机不多,关于虚拟机的问题我可能解决不了,有问题可以发在群里,大家一起解决。
- 虚拟机的安装:
群里同学发的:八分钟完成VMware和ubuntu系统安装_哔哩哔哩_bilibili
- 虚拟机中如何打开Terminal(终端):
ubuntu桌面版打开终端Terminal的几种方法_lida2003的博客-CSDN博客_terminal ubuntu
ubuntu怎样打开命令行终端(5种方法 DemonHunter211的博客-CSDN博客_ubuntu怎么调出命令窗口
云服务器
想要探索一下的同学可以尝试一下。有学生优惠,买个云服务器其实很便宜!
共建智能世界云底座-华为云 (huaweicloud.com)
美团云(MOS) - 云主机_云服务器_云计算_美团网云平台,基础设施服务,稳定提升价值 (mtyun.com)
AWS 云服务-专业的大数据和云计算服务以及云解决方案提供商 (amazon.com)
双系统
个人不是很推荐,因为很可能两个系统都用不了了!
微信群问题汇总
关于安装路径 | WSL的安装通过Microsoft Store,目前是只能安装在C盘。WSL可能必须在C盘,我之前尝试过移动到别的盘,但是会出现很多的问题 |
---|---|
关于WSL是什么 | 我们只安装的Linux发行版Ubuntu的命令行,没有安装桌面,所以这个黑黑的命令行就是所有,一切的操作均在这个命令行中。 |
密码输入不了问题 | 密码不是输入不了,是输入了但是不显示,输入完成之后直接enter就行。 |
设置root密码 | sudo passwd root |
用户与用户组 | root代表的是超级用户,拥有Linux的绝对权限。 平时使用最好可以建一个普通用户,如果涉及到权限的话,使用sudo,或者是使用su -切换到root,更好些吧。 Linux中有个非常重要的概念用户和用户组 这个murphy是一个普通用户,这个root是个超级用户,有绝对的权限。 |
关于权限 | |
用WSL还算虚拟机 | WSL只有命令行,虚拟机下载的是完整的Ubuntu,有桌面,更符合Windows的使用习惯。使用WSL做C的学习和开发完全够用,老师也说了,用哪个都行! 老师要求我们在Linux系统上学习C的编程。大部分的人的电脑都是Windows吧。要想实现Windows上的Linux,要么使用WSL,要么使用虚拟机VM创建一个Ubuntu系统,要么云服务器。 MacOS的同学直接用系统的终端就行了。 |
进入系统
关于用户
很多同学是以root用户登陆的,可以用,但从长期来说,我感觉不合适(未来学了多了的话,可以使用adduser
创建新用户)
另外一部分同学是两个用户,一个xxx(你自己注册是用的名字)和一个root。
以我自己的为例,我的普通用户是ubuntu
,管理员用户是root
。
从ubuntu
切换到root
的命令:先输入su
或者su -
,然后再按enter
;
su- 与su的区别 - 且如歌 - 博客园 (cnblogs.com)
总结:有没有切换PATH环境变量
从root
切换到ubuntu
:Ctrl+D
或者su unbuntu
最好的情况是应该这样的(**忽略掉(base)**)
pt112:这是一个conda虚拟环境表示,大家应该都没有conda环境,所以没有这个,忽略就行!
ubuntu:这是我都普通用户的用户名,大家的可能不一样
@VM-S-15-ubuntu:是我的Linux主机的名称,大家的可能不一样
~:代表的是/home/ubuntu路径,每个人的都不同,但都是/home/“普通用户名”
$:表示的是普通用户,#表示的root用户
Linux有非常重要的文件结构,未来学的多了,就熟悉了,目前先熟悉两个!
/
:根目录
/home
:根目录下的home目录(说明:有两个用户的同学,会发现这个目录先有个文件夹的名字和注册的名字一样)
1 |
|
关于命令
Linux的命令实在是太多了,记住是不可能的,用到什么要学会使用搜索引擎,自己尝试解决问题
老师推荐了一个很好的查询命令的网站:Linux命令搜索引擎 命令,Linux Linux命令搜索引擎 命令详解:最专业的Linux命令大全,内容包含Linux命令手册、详解、学习,值得收藏的Linux命令速查手册。 - Linux 命令搜索引擎 (wangchujiang.com)
另外,菜鸟教程也很不错:Linux 命令大全 | 菜鸟教程 (runoob.com)
推荐三本书:
Linux命令行与shell脚本编程大全(第3版) (豆瓣) (douban.com)
鸟哥的Linux私房菜 基础学习篇 第四版 (豆瓣) (douban.com)
《鸟哥的Linux私房菜》也很不错,但这本书是以Linux的另一个发行版CentOS举例的。CentOS用在企业级的服务器可能多一点
第一周课堂(上机课)练习
练习1 文件操作
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
练习2 程序编写与编译
Linux中自带了vim,不需要下载!
Vim基本语法与使用方法:Vim|Murphy
- GCC安装
教程链接:如何在 Ubuntu 20.04 上安装 GCC(build-essential)-阿里云开发者社区 (aliyun.com)
默认的 Ubuntu 软件源包含了一个软件包组,名称为 “build-essential”,它包含了 GNU 编辑器集合,GNU 调试器,和其他编译软件所必需的开发库和工具。
想要安装开发工具软件包,以 拥有 sudo 权限用户身份或者 root 身份运行下面的命令:
1 |
|
通过运行下面的命令,打印 GCC 版本,来验证 GCC 编译器是否被成功地安装。(在 Ubuntu 20.04 软件源中 GCC 的默认可用版本号为9.3.0
:)
1 |
|
- 文件的编写与运行
1 |
|
1 |
|
1 |
|
1 |
|
第二周 计算机简介
2 | 第二周 | 2022年09月15日周四 | 计算机的历史与未来;程序运行的基本原理;操作系统与编程语言。 | 幻灯片 |
---|---|---|---|---|
L2 | 第二周 | 2022年09月15日周四 | 实验课二:熟悉Linux操作系统下的编程环境。 | 实验手册 |
Linux简介
Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年10月5日首次发布,它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的Unix工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。Linux有上百种不同的发行版,如基于社区开发的debian、archlinux,和基于商业开发的Red Hat Enterprise Linux、SUSE等。
Shell
1 |
|
Linux 目录结构
Linux 系统目录结构 | 菜鸟教程 (runoob.com)
/bin:
bin 是 Binaries (二进制文件) 的缩写, 这个目录存放着最经常使用的命令。/boot:
这里存放的是启动 Linux 时使用的一些核心文件,包括一些连接文件以及镜像文件。/dev :
dev 是 Device(设备) 的缩写, 该目录下存放的是 Linux 的外部设备,在 Linux 中访问设备的方式和访问文件的方式是相同的。/etc:
etc 是 Etcetera(等等) 的缩写,这个目录用来存放所有的系统管理所需要的配置文件和子目录。/home:
用户的主目录,在 Linux 中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的,如上图中的 alice、bob 和 eve。/lib:
lib 是 Library(库) 的缩写这个目录里存放着系统最基本的动态连接共享库,其作用类似于 Windows 里的 DLL 文件。几乎所有的应用程序都需要用到这些共享库。/lost+found:
这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。/media:
linux 系统会自动识别一些设备,例如U盘、光驱等等,当识别后,Linux 会把识别的设备挂载到这个目录下。/mnt:
系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在 /mnt/ 上,然后进入该目录就可以查看光驱里的内容了。/opt:
opt 是 optional(可选) 的缩写,这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。/proc:
proc 是 Processes(进程) 的缩写,/proc 是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。
这个目录的内容不在硬盘上而是在内存里,我们也可以直接修改里面的某些文件,比如可以通过下面的命令来屏蔽主机的ping命令,使别人无法ping你的机器:
1
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
/root:
该目录为系统管理员,也称作超级权限者的用户主目录。/sbin:
s 就是 Super User 的意思,是 Superuser Binaries (超级用户的二进制文件) 的缩写,这里存放的是系统管理员使用的系统管理程序。/selinux:
这个目录是 Redhat/CentOS 所特有的目录,Selinux 是一个安全机制,类似于 windows 的防火墙,但是这套机制比较复杂,这个目录就是存放selinux相关的文件的。/srv:
该目录存放一些服务启动之后需要提取的数据。/sys:
这是 Linux2.6 内核的一个很大的变化。该目录下安装了 2.6 内核中新出现的一个文件系统 sysfs 。
sysfs 文件系统集成了下面3种文件系统的信息:针对进程信息的 proc 文件系统、针对设备的 devfs 文件系统以及针对伪终端的 devpts 文件系统。
该文件系统是内核设备树的一个直观反映。
当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。
/tmp:
tmp 是 temporary(临时) 的缩写这个目录是用来存放一些临时文件的。/usr:
usr 是 unix shared resources(共享资源) 的缩写,这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于 windows 下的 program files 目录。/usr/bin:
系统用户使用的应用程序。/usr/sbin:
超级用户使用的比较高级的管理程序和系统守护程序。/usr/src:
内核源代码默认的放置目录。/var:
var 是 variable(变量) 的缩写,这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。/run:
是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。如果你的系统上有 /var/run 目录,应该让它指向 run。在 Linux 系统中,有几个目录是比较重要的,平时需要注意不要误删除或者随意更改内部文件。
/etc: 上边也提到了,这个是系统中的配置文件,如果你更改了该目录下的某个文件可能会导致系统不能启动。
/bin, /sbin, /usr/bin, /usr/sbin: 这是系统预设的执行文件的放置目录,比如 ls 就是在 /bin/ls 目录下的。
值得提出的是 /bin、**/usr/bin** 是给系统用户使用的指令(除 root 外的通用用户),而/sbin, /usr/sbin 则是给 root 使用的指令。
/var: 这是一个非常重要的目录,系统上跑了很多程序,那么每个程序都会有相应的日志产生,而这些日志就被记录到这个目录下,具体在 /var/log 目录下,另外 mail 的预设放置也是在这里。
helloworld问题再记录
系统问题:第一周➡开发环境
开发环境问题:第一周➡第一周课堂(上机课)练习➡练习2 程序编写与编译➡vim&GCC安装
⭐建议用桌面端浏览器进行观看,页面右侧有导航栏可以直接跳转
再记录的内容重点是权限问题,这又涉及到第一周➡进入系统➡关于用户
的内容了。
只有一个root登陆WSL的同学,可以采用下面这个链接的方式(我测试过了,可用),但是有点麻烦;第二种方法就是卸载了WSL重装!
使用普通用户登陆Linux的同学,建议把课堂下的文件放在~
下,在这个文件夹下建立文件是不需要权限的(至于是为什么,读一下上面这张图片,或许可以明白!)
1 |
|
举了例子!
apt 换源
ubuntu | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
ubuntu镜像_ubuntu下载地址_ubuntu安装教程-阿里巴巴开源镜像站 (aliyun.com)
Ubuntu 20.04 && Ubuntu 18.04 修改 apt 源_星汉空兮的博客-CSDN博客
之前安装系统的时候,大部分同学安装的都是Ubuntu 20.04,但也有同学安装了22.04,换apt的源的时候,需要自己注意一下!
1 |
|
1 |
|
1 |
|
1 |
|
sudo apt-get update 与upgrade的用法_Darren_pty的博客-CSDN博客_apt-get update
第三周 程序简介
3 | 第三周 | 2022年09月22日周四 | 感性认识计算机程序;快步走进C程序。 | 幻灯片 |
---|---|---|---|---|
L3 | 第三周 | 2022年09月22日周四 | 实验课三:C程序的编译、运行和调试。 | 实验手册 |
C程序编译过程
gdb介绍
gdb下载:Ubuntu1804下安装gdb与使用 - michaelchengjl - 博客园 (cnblogs.com)
1 |
|
学习资料:
GDB 入门教程_恋喵大鲤鱼的博客-CSDN博客_gdb教程
gdb的基本用法_一只向前的程序猿的博客-CSDN博客_gdb用法
GDB十分钟教程_Liigo的博客-CSDN博客_gdb教程。
Linux 使用gdb调试入门。_哔哩哔哩_bilibili
程序中的错误主要分为 2 类,分别为语法错误和逻辑错误:
- 程序中的语法错误几乎都可以由编译器诊断出来,很容易就能发现并解决;
- 逻辑错误指的是代码思路或者设计上的缺陷,程序出现逻辑错误的症状是:代码能够编译通过,没有语法错误,但是运行结果不对。对于这类错误,只能靠我们自己去发现和纠正。
也就是说,程序中出现的语法错误可以借助编译器解决;但逻辑错误则只能靠自己解决。实际场景中解决逻辑错误最高效的方法,就是借助调试工具对程序进行调试。
调试器名称 | 特 点 |
---|---|
Remote Debugger | Remote Debugger 是 VC/VS 自带的调试器,与整个IDE无缝衔接,使用非常方便。 |
WinDbg | 大名鼎鼎的 Windows 下的调试器,它的功能甚至超越了 Remote Debugger,它还有一个命令行版本(cdb.exe),但是这个命令行版本的调试器指令比较复杂,不建议初学者使用。 |
LLDB | XCode 自带的调试器,Mac OS X 下开发必备调试器。 |
GDB | Linux 下使用最多的一款调试器,也有 Windows 的移植版。 |
正如从事 Windows C/C++ 开发的一定要熟悉 Visual Studio、从事 Java 开发的要熟悉 Eclipse 或 IntelliJ IDEA、从事 Android 开发的要熟悉 Android Studio、从事 iOS 开发的要熟悉 XCode 一样,从事 Linux C/C++ 开发要熟悉 GDB。
1 |
|
GDB基本用法
GDB基本用法 - Euphie - 博客园 (cnblogs.com)
- 基本命令
- 进入GDB:#gdb test
test是要调试的程序,由gcc test.c -g -o test生成。进入后提示符变为(gdb) 。
- 查看源码:(gdb) l
源码会进行行号提示。
如果需要查看在其他文件中定义的函数,在l后加上函数名即可定位到这个函数的定义及查看附近的其他源码。或者:使用断点或单步运行,到某个函数处使用s进入这个函数。
- 设置断点:(gdb) b 6
这样会在运行到源码第6行时停止,可以查看变量的值、堆栈情况等;这个行号是gdb的行号。
- 查看断点处情况:(gdb) info b
可以键入”info b”来查看断点处情况,可以设置多个断点;
- 运行代码:(gdb) r
- 显示变量值:(gdb) p n
在程序暂停时,键入”p 变量名”(print)即可;
GDB在显示变量值时都会在对应值之前加上 N N”,而无需写冗长的变量名;
- 观察变量:(gdb) watch n
在某一循环处,往往希望能够观察一个变量的变化情况,这时就可以键入命令”watch”来观察变量的变化情况,GDB在”n”设置了观察点;
- 单步运行:(gdb) n
- 程序继续运行:(gdb) c
使程序继续往下运行,直到再次遇到断点或程序结束;
- 退出GDB:(gdb) q
- 断点调试
命令格式 | 例子 | 作用 |
---|---|---|
break + 设置断点的行号 | break n | 在n行处设置断点 |
tbreak + 行号或函数名 | tbreak n/func | 设置临时断点,到达后被自动删除 |
break + filename + 行号 | break main.c:10 | 用于在指定文件对应行设置断点 |
break + <0x…> | break 0x3400a | 用于在内存某一位置处暂停 |
break + 行号 + if + 条件 | break 10 if i==3 | 用于设置条件断点,在循环中使用非常方便 |
info breakpoints/watchpoints [n] | info break | n表示断点编号,查看断点/观察点的情况 |
clear + 要清除的断点行号 | clear 10 | 用于清除对应行的断点,要给出断点的行号,清除时GDB会给出提示 |
delete + 要清除的断点编号 | delete 3 | 用于清除断点和自动显示的表达式的命令,要给出断点的编号,清除时GDB不会给出任何提示 |
disable/enable + 断点编号 | disable 3 | 让所设断点暂时失效/使能,如果要让多个编号处的断点失效/使能,可将编号之间用空格隔开 |
awatch/watch + 变量 | awatch/watch i | 设置一个观察点,当变量被读出或写入时程序被暂停 |
rwatch + 变量 | rwatch i | 设置一个观察点,当变量被读出时,程序被暂停 |
catch | 设置捕捉点来补捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常 | |
tcatch | 只设置一次捕捉点,当程序停住以后,应点被自动删除 |
- 数据命令
命令格式 | 例子 | 作用 |
---|---|---|
display +表达式 | display a | 用于显示表达式的值,每当程序运行到断点处都会显示表达式的值 |
info display | 用于显示当前所有要显示值的表达式的情况 | |
delete + display 编号 | delete 3 | 用于删除一个要显示值的表达式,被删除的表达式将不被显示 |
disable/enable + display 编号 | disable/enable 3 | 使一个要显示值的表达式暂时失效/使能 |
undisplay + display 编号 | undisplay 3 | 用于结束某个表达式值的显示 |
whatis + 变量 | whatis i | 显示某个表达式的数据类型 |
print(p) + 变量/表达式 | p n | 用于打印变量或表达式的值 |
set + 变量 = 变量值 | set i = 3 | 改变程序中某个变量的值 |
- 在使用print命令时,可以对变量按指定格式进行输出,其命令格式为print /变量名 + 格式,其中常用的变量格式:x:十六进制;d:十进制;u:无符号数;o:八进制;c:字符格式;f:浮点数。
- 调试运行环境相关命令
命令格式 | 例子 | 作用 |
---|---|---|
set args | set args arg1 arg2 | 设置运行参数 |
show args | show args | 参看运行参数 |
set width + 数目 | set width 70 | 设置GDB的行宽 |
cd + 工作目录 | cd ../ | 切换工作目录 |
run | r/run | 程序开始执行 |
step(s) | s | 进入式(会进入到所调用的子函数中)单步执行,进入函数的前提是,此函数被编译有debug信息 |
next(n) | n | 非进入式(不会进入到所调用的子函数中)单步执行 |
finish | finish | 一直运行到函数返回并打印函数返回时的堆栈地址和返回值及参数值等信息 |
until + 行数 | u 3 | 运行到函数某一行 |
continue(c) | c | 执行到下一个断点或程序结束 |
return <返回值> | return 5 | 改变程序流程,直接结束当前函数,并将指定值返回 |
call + 函数 | call func | 在当前位置执行所要运行的函数 |
- 堆栈相关命令
命令格式 | 例子 | 作用 |
---|---|---|
backtrace/bt | bt | 用来打印栈帧指针 |
frame | frame 1 | 用于打印指定栈帧 |
info reg | info reg | 查看寄存器使用情况 |
info stack | info stack | 查看堆栈使用情况 |
up/down | up/down | 跳到上一层/下一层函数 |
1 |
|
- 跳转执行
- jump:指定下一条语句的运行点。可以是文件的行号,可以是file:line格式,可以是+num这种偏移量格式。表式着下一条运行语句从哪里开始。相当于改变了PC寄存器内容,堆栈内容并没有改变,跨函数跳转容易发生错误。
- 信号命令
- signal:signal SIGXXX,产生XXX信号,如SIGINT。一种速查Linux查询信号的方法:# kill -l
- 运行Shell命令
- 如(gdb)shell ls来运行ls
- 更多程序运行选项和调试
- 程序运行参数
1 |
|
- 运行环境
1 |
|
- 工作目录
1 |
|
- 程序的输入输出
1 |
|
- 调试已运行的程序
1 |
|
- 暂停 / 恢复程
1 |
|
- 线程(Thread Stops)
1 |
|
- 调试core文件
- Core Dump:Core的意思是内存,Dump的意思是扔出来,堆出来。开发和使用Unix程序时,有时程序莫名其妙的down了,却没有任何的提示(有时候会提示core dumped),这时候可以查看一下有没有形如core.进程号的文件生成,这个文件便是操作系统把程序down掉时的内存内容扔出来生成的, 它可以做为调试程序的参考
- 生成Core文件
1 |
|
- 用gdb查看core文件
1 |
|
- 用gdb实时观察某进程crash信息
1 |
|
第四周 计算机程序
4 | 第四周 | 2022年09月29日周四 | 从现实问题到计算机程序。 | 幻灯片 |
---|---|---|---|---|
L4 | 第四周 | 2022年09月29日周四 | 实验课四:感性接触C程序。 | 实验手册 |
第五周 C语言简介
5 | 第五周 | 2022年10月06日周四 | C语言的由来、标准和构成;数据成分。 | 幻灯片 |
---|---|---|---|---|
L5 | 第五周 | 2022年10月06日周四 | 实验课五:C语言的数据成分。 | 实验手册 |
C语言规范定义的非常宽泛:long
型数据长度不短于int
型;short
型不长于int
型
-> 相同的程序在不同编译器上具有不同解释
-> 相同的程序在不同平台上运行结果不同
冒泡排序算法
1 |
|
1 |
|
第六周 运算控制传输
6 | 第六周 | 2021年10月13日周四 | 运算成分;控制成分;传输成分。 | 幻灯片 |
---|---|---|---|---|
L6 | 第六周 | 2022年10月13日周四 | 实验课六:C语言的数据、运算和控制成分。 | 实验手册 |
推荐网课:翁恺C语言_哔哩哔哩_bilibili
控制成分
break:在switch语句、while语句、 do-while语句、for语句中使用; 以跳出switch语句或内层循环,继续执行逻辑上的下一条语句。
continue:用于循环语句中; 结束本次循环,接着立即测试循环控制表达式,判断是否继续执行下一次循环。
传输成分
scanf的工作原理
scanf是从标准输入中读取字符,然后进行相关转化;
如果是空格或者换行,直接跳过;
如果不符合格式化要求,不处理同时也不减少缓冲区中的信息。
将数据按照行缓冲送到键盘缓冲区; 按照格式化要求从缓冲区中读取数据到相应内存空间。
scanf并不能保证后面的参数都被正确赋值。scanf是格式化输入,printf是格式化输出。
cin是输入流,cout是输出流。
格式化输出效率比较高,但是写代码麻烦。
流输出操作效率稍低,但书写简便。
cout之所以效率低,是先把要输出的东西存入缓冲区再输出。
以下参考:”C Primer Plus”
scanf
buffer
其他参考资料:
scanf函数%c前为什么加空格_hhhhhyyyyy8的博客-CSDN博客
c语言防止缓冲区数据作为有效字符被读入 - cmustard - 博客园 (cnblogs.com)
第七周 数组
7 | 第七周 | 2022年10月20日周四 | 数组。 | 幻灯片 |
---|---|---|---|---|
L7 | 第七周 | 2022年10月20日周四 | 实验课七:C语言的数组。 | 实验手册 |
第八周 字符串
8 | 第八周 | 2022年10月27日周四 | 字符串。 | 幻灯片 |
---|---|---|---|---|
L8 | 第八周 | 2022年10月27日周四 | 实验课八:C语言的字符串。 | 实验手册 |
C语言中的字符串是个难点!
C++中的输入
cin
- string str; cin >> str; 接受一个字符串,遇“空格”、“TAB”、“回车”都结束
cin.get()
- cin.get(ch),可以用来接收一个字符
- cin.get(字符数组名,接收字符数目)用来接收一行字符串,可以接收空格
- cin.get(无参数)没有参数主要是用于舍弃输入流中的不需要的字符,或者舍弃回车,弥补cin.get(字符数组名,接收字符数目)的不足.
cin.getline()
- 接受一个字符串,可以接收空格并输出
getchar()
getline(cin, string)// 需要string的头文件
- 第一个参数是输入流对象、第二个参数是保存字符串的字符串对象。getline从输入流中读取对象保存到string中,但是不包括换行符,这样就可以保存一行中的空格、制表符了。
C中的输入
- scanf(“%d”, &aa);
- scanf(“%f”, &bb);
- scanf(“%c”, &ch);
- 输入一个字符。
- scanf(“%s”, str); //用scanf把字符串读入字符数组中,不需要&
- 从第一个非空白字符开始,到下一个空白字符之前的所有的字符都是输入。(简单来讲,就是只能输入一个单词)
- ch = getchar();// 输入一个字符
- putchar(ch); // 输出一个字符
- gets(str);(C11中不能用了)
- 读取整行输入,直到遇到换行符,然后丢弃换行符,存储其余字符,并在这些字符的末尾添加一个空字符使其成为一个C字符串。
- C11标准中,直接废除了gets()函数!因为可能有缓冲区溢出的安全隐患!
- puts(str); 输出字符串。
- fgets(str, STLEN, stdin);
- STLEN是读入字符的最大数量。
- 如果fgets()读到一个换行符,会把他存储到字符串中。这一点与gets()不一样。
- fputs(str, stdout); 输入
- gets_s(str, STLEN); (C11 中新增的)
第九周 函数
9 | 第九周 | 2022年11月03日周四 | 函数。 | 幻灯片 |
---|---|---|---|---|
L9 | 第九周 | 2022年11月03日周四 | 实验课九:C语言的函数。 | 实验手册 |
- 函数原型;函数声明
- 参数传递:值传递
- 实参与形参具有不同的存储单元,实参与形参变量的数据传递是 “值传递”。
- 函数调用时,系统给形参分配存储单元,并将实参对应的值传递给形参。
- 实参与形参的类型必须相同或可以兼容。
- 局部变量/全局变量
- 局部变量:在函数内或块内定义,只在这个函数或块内起作用。
- 全局变量:在所有函数外定义,作用域从定义变量的位置开始到本程序文件结束。
- 当全局变量与局部变量同名时,局部变量将在自己作用域内有效,它将屏蔽同名的全局变量。
- 不在非常必要的情况下,不要使用全局变量。
- 数组与函数
- 数组元素作为函数参数
- 数组名(地址)作为函数参数:数组名就是数字在内存中的地址
- 形式参数是一个未定义大小的数组:void myFunction(int param[])
- 形式参数是一个已定义大小的数组:void myFunction(int param[10])
- 形式参数是一个指针:void myFunction(int *param)
第十周 递归
10 | 第十周 | 2022年11月10日周四 | 递归。 | 幻灯片 |
---|---|---|---|---|
L10 | 第十周 | 2022年11月10日周四 | 实验课十:C语言的递归。 | 实验手册 |
- 递归简单来说就是函数的嵌套。
- 递归:一个函数在其定义中直接或间接调用自身的一种方法。
- 递归与递推
- 不同:递推的关注点放在起始点条件;递归的关注点放在求解目标上、
- 相同:重在表现第 i 次与第 i + 1次的关系
- 斐波那契数列;进制转换;汉诺塔;逆波兰表达式;放苹果(把这几个例子动手实现看看)
第十一周 指针
11 | 第十一周 | 2022年11月17日周四 | 指针(一)。 | 幻灯片 |
---|---|---|---|---|
L11 | 第十一周 | 2022年11月17日周四 | 实验课十一:C语言的指针(一)。 | 实验手册 |
指针!难点!
指针是什么
变量三要素:变量的地址*(变量在内存重点位置)*,变量的值,变量的名字
指针:把某个变量的地址称为“指向该变量的指针”
如何知道一个变量的地址:取地址符‘&’
指针运算符 ‘*’
1 |
|
- 指针变量:存放地址(指针)的变量
- 定义一个指针变量
1 |
|
1 |
|
- 指针变量也是变量,是变量就有地址
1 |
|
第十二周 指针
12 | 第十二周 | 2022年11月24日周四 | 指针(二)。 | 幻灯片 |
---|---|---|---|---|
L12 | 第十二周 | 2022年11月24日周四 | 实验课十二:C语言的指针(二)。 | 实验手册 |
数组与指针
数组名代表数组首元素的地址;数组名是指向数组第一个元素的指针;注意:a是地址常量,不是变量,不能给其赋值。
1 |
|
- 利用指针变量引用数组元素
1 |
|
字符串与指针
1 |
|
第十三周 指针
13 | 第十三周 | 2022年12月01日周四 | 指针(三)。 | 幻灯片 |
---|---|---|---|---|
L13 | 第十三周 | 2022年12月01日周四 | 实验课十三:C语言的指针(三)。 | 实验手册 |
二维数组与指针
1 |
|
1 |
|
函数与指针
- 指针变量做函数参数
- 数组名做函数参数
- 多维数组名做函数参数
- 一般而言,声明一个指向N维数组的指针时,只能省略最左边方括号中值。
- 一般而言,声明一个指向N维数组的指针时,只能省略最左边方括号中值。
- 指向符号常量的指针
- 返回指针值的函数
1 |
|
- 静态局部变量
- 函数中的局部变量的值在函数调用结束后不消失而保留原值;
- 即其占用的存储单元不释放,在下一次该函数调用时,仍可以继续使用该变量。
- 用关键词static进行声明
第十四周 结构体和链表
14 | 第十四周 | 2022年12月08日周四 | 结构体与链表。 | 幻灯片 |
---|---|---|---|---|
L14 | 第十四周 | 2022年12月08日周四 | 实验课十四:C语言的结构体与链表。 | 实验手册 |
结构体
- 结构体的定义
1 |
|
1 |
|
- 应用举例
1 |
|
- 结构体做函数参数
1 |
|
- 结构体做函数返回值
1 |
|
- 指向结构体的指针
1 |
|
1 |
|
C 语言中,「.」与「->」有什么区别? - 知乎 (zhihu.com)
【转】C语言中 -> 是什么意思?_c语言中->表示什么_littesss的博客-CSDN博客
->
是一个整体,它是用于指向结构体、C++中的class等含有子数据的指针用来取子数据。换种说法,如果我们在C语言中定义了一个结构体,然后申明一个指针指向这个结构体,那么我们要用指针取出结构体中的数据,就要用到
->
.
- 结构体数组
1 |
|
链表
用指针把结构体链起来
链表头:指向第一个链表结点的指针。
链表结点:链表中的每一个元素,包括:
- ▶ 当前节点的数据; \
- ▶ 下一个结点的地址。
链表尾:不再指向其他结点的结点,其地址部分放一个NULL,表示链表到此结束。
第十五周 面向对象
15 | 第十五周 | 2022年12月15日周四 | 面向对象程序设计。 | 幻灯片 |
---|---|---|---|---|
L15 | 第十五周 | 2022年12月15日周四 | 实验课十五:C程序设计(综合)。 | 实验手册 |
第十六周 总结复习
16 | 第十六周 | 2022年12月22日周四 | 课程总结。 |
---|---|---|---|
L16 | 第十六周 | 2022年12月22日周四 | 实验课十六:程序设计实践。 |
期末复习
重点习题
1 pre9 冒泡排序
1 |
|
2 pre12 整数1 5 10的个数
1 |
|
3 pre19 细菌实验分组
1 |
|
4 pre24 分离整数的各位数
1 |
|
5 pre25 成绩判断
1 |
|
6 pre43 找和为K的两个元素
1 |
|
7 pre49 最长单词
1 |
|
8 pre51 循环移动
1 |
|
9 pre55 简单计算器
1 |
|
10 pre56 角谷猜想
1 |
|
11 pre58 括号匹配
1 |
|
12 pre59 判断闰年
1 |
|
13 pre60 寻找下标
1 |
|
14 pre63 四大湖
1 |
|
15 pre66 文字排版
1 |
|
16 pre70 矩阵边缘
1 |
|
17 pre72 配对碱基链
1 |
|
18 pre310 跳跃游戏
1 |
|
19 pre311 合法括号
1 |
|
20 pre312 含k个3的数
1 |
|
21 pre314 运算符判定
1 |
|
知识点复习
条件控制
- 什么时候用if、if-if-if-if……、if-else、if-else if-else if-else
关系运算、逻辑运算
- &&
- ||
- !
循环
- for
- while
- do while
整数取余、取赏
- x%10
- x\10(这里是利用是int型变量的特性,利用除法巧妙地去掉最后一位数。)
特殊类型整数分析判断:素数、偶数、最大公约数、最小公倍数、回文数
- 素数(质数)
1 |
|
- 最大公约数(最大公因数)GCD & 最小公倍数LCM
1 |
|
1 |
|
- 回文数
1 |
|
十进制与二进制转换(位运算)
1 |
|
运算符 | 作用 | 示例 |
---|---|---|
& | 按位与 | 两个操作数同时为1结果为1,只要有一个为0,结果为0 |
| | 按位或 | 两个操作数只要有一个为1,结果就为1 |
~ | 按位非 | 操作数为1,结果为0;操作数为0,结果为1 |
^ | 按位非 | 两个操作数相同,结果为0;不相同结果为1 |
<< | 左移 | 右侧空位补0,左侧溢出舍弃 |
>> | 右移 | 右端溢出舍弃,对于无符号数,高位补0。对于有符号数,某些机器将对左边空出的部分用符号位填补(即“算术移位”) |
数组的定义、使用(元素访问、排序、修改值)
函数的基本定义和实现
字符串的基本处理:统计长度、数量
递归运算
斐波那契数列;进制转换;汉诺塔;逆波兰表达式;放苹果(把这几个例子动手实现看看)
斐波那契数列
1 |
|
- 进制转换
1 |
|
- 汉诺塔
1 |
|
- 逆波兰表达式
逆波兰表示法在求值时不需要使用括号,也不需要考虑优先级。
比如:
1 + 1 * 2
转换为1 1 2 * +
,(1 + 1) * 2
转换为1 1 + 2 *
。
C++实现逆波兰表达式的例题详解_C 语言_脚本之家 (jb51.net)
- 放苹果
递推递归算法解决放苹果问题:把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
1 |
|
拓展内容
常用编辑器与编译器
Windows
- Microsoft Visual Studio ⭐
Visual Studio 2022 IDE - 适用于软件开发人员的编程工具 (microsoft.com)
免费的开发人员软件和服务 - Visual Studio (microsoft.com)
在我心中Visual Studio 是全宇宙最强大的IDE(非嵌入式领域),唯唯诺诺(bushi)的Microsoft在VS这里我觉得是真巨硬!
集成开发环境(Integrated Development Environment,简称IDE,也称为Integration Design Environment、Integration Debugging Environment)是一种辅助程序开发人员开发软件的应用软件,在开发工具内部就可以辅助编写源代码文本、并编译打包成为可用的程序,有些甚至可以设计图形接口。
IDE通常包括编程语言编辑器、自动构建工具、通常还包括调试器。有些IDE包含编译器/解释器,如微软的Microsoft Visual Studio,有些则不包含,如Eclipse、SharpDevelop等,这些IDE是通过调用第三方编译器来实现代码的编译工作的。有时IDE还会包含版本控制系统和一些可以设计图形用户界面的工具。许多支持面向对象的现代化IDE还包括了类别浏览器、对象查看器、对象结构图。虽然目前有一些IDE支持多种编程语言(例如Eclipse、NetBeans、Microsoft Visual Studio),但是一般而言,IDE主要还是针对特定的编程语言而量身打造(例如Visual Basic、Spyder)。
编辑器:VS的用户界面
编译器:Visual C++ (简称 MSVC)
一个现代编译器的主要工作流程:源代码 (source code) →预处理器 (preprocessor) → 编译器 (compiler) → 汇编程序 (assembler) → 目标代码 (object code) → 链接器 (Linker) → 可执行程序 (executables)。
VS的编译器使用的是Visual C++ (简称 MSVC)是由微软开发的,只能用于 Windows 操作系统。
- 优点:功能强大,非常非常强大!!!
- 缺点:操作较为复杂,更适合用在大型项目的开发中;过高的安全性,Microsoft为了追求安全性对很多函数进行了自定义,使用C/C++的标准函数时,VS会直接报错;软件非常大,好像差不多20+GB。
- 总结:VS非常强大,但非适合所有的人,我平时用的最多的编程语言并不是C/C++,并且写C/C++时,也不怎么写很大的程序,所以我平时用VS很少,主要用下面提及的几种工具。但对于初学者来说,使用VS也算是一个不错的选择(有利有弊),开发环境都配置好了,基本上来说就是无脑操作。
- Microsoft Visual Studio Code + MinGW-W64 GCC⭐
Visual Studio Code - Code Editing. Redefined
MinGW-w64 - for 32 and 64 bit Windows download | SourceForge.net
编辑器:VScode
编译器:MinGW-W64 GCC
- VScode
Microsoft在开源领域之前是做到非常差的,什么软件都和Windows进行捆绑,但Visual Studio Code的出现,让我对Microsoft有了一个新看法。
VScode全称是Visual Studio Code,是微软推出的一个跨平台的编辑器,能够在windows、Linux、IOS等平台上运行,通过安装一些插件可以让这个编辑器变成一个编译器。 VSCode支持C++、Python、Java、C#、Go等多种语言,功能强大、插件丰富并且启动速度极快,值得每个开发人员尝试一把!
简单来说,VSCode就是一个非常厉害的文本编辑器,但是他支持插件,配置好环境之后就能编写程序,编译,调试,运行。当VScode配置好开发环境之后,就相当于一个精简版的VS了。
- MinGW-W64 GCC
MinGW 提供了一套简单方便的Windows下的基于GCC 程序开发环境。MinGW 收集了一系列免费的Windows 使用的头文件和库文件;同时整合了GNU ( http://www.gnu.org/ )的工具集,特别是GNU 程序开发工具,如经典gcc, g++, make等。MinGW是完全免费的自由软件,它在Windows平台上模拟了Linux下GCC的开发环境,为C++的跨平台开发提供了良好基础支持,为了在Windows下工作的程序员熟悉Linux下的C++工程组织提供了条件。
- 优点:简介,自定义程度强
- 缺点:配置环境较复杂,学习成本也比较高
- 总结:VScode是我目前用的比较多的,基本上所有我会的开发语言,我都会在VScode上进行。对于初学者可能要有一定的学习成本,但如果对VS的过于复杂的功能所困扰的话,可以尝试一下VScode + MinGW-W64 GCC
- Sublime Text + Microsoft Terminal + MinGW-W64 GCC⭐
Sublime Text - Text Editing, Done Right
Windows Terminal installation | Microsoft Docs
MinGW-w64 - for 32 and 64 bit Windows download | SourceForge.net
这三个工具的组合本质上和 Microsoft Visual Studio Code + MinGW-W64 GCC 的功能一模一样!!但使用起来这三个工具的组合更像Vim + GCC。
Sublime Text比记事本功能强,比VSCode功能弱。
- Vim + Microsoft Terminal + MinGW-W64 GCC
Windows Terminal installation | Microsoft Docs
MinGW-w64 - for 32 and 64 bit Windows download | SourceForge.net
没想到吧!Windows下也有Vim。不赘述了
- Dev-C++
Dev-C++ download | SourceForge.net
对于Dev-C++我用的不是很多,只在我的Surface Go电脑上配置了一下,但也没怎么用过,也许可以说是低配版VS(?)
编辑器:Dev-C++的用户界面
编译器:MingW64/TDM-GCC
dev c++是什么编译器?有什么优缺点? - 行业资讯 - 亿速云 (yisu.com)
- CLion + MinGW-W64 GCC
CLion: A Cross-Platform IDE for C and C++ by JetBrains
CLion是一个编辑器,没有内置编译和调试工具,所有也是要搭配MinGW-W64 GCC才能使用的。
CLion是商业软件,需要收费,我用的不是很多,不再赘述。
需要介绍一下的是Jet Brains,CLion就是该公司推出的一个软件,该公司的其他软件也非常有名且好用!
Jet Brains是一家捷克的软件开发公司,该公司位于捷克的布拉格!
IDE
- Fleet - 下一代JetBrains 的 IDE
- AppCode - 适用于[ iOS](https://baike.baidu.com/item/ iOS/45705?fromModule=lemma_inlink)/macOS 开发的智能 IDE
- CLion - 支持 C 和 C++ 的跨平台 IDE
- DataGrip - 多种数据库,一个工具
- GoLand - 专为 Go 开发者设计的跨平台 IDE
- [IntelliJ IDEA](https://baike.baidu.com/item/IntelliJ IDEA?fromModule=lemma_inlink) - 功能强大,符合人体工程学的 JVM IDE (用过⭐)
- PHPStorm - 高效智能的 PHP 集成开发工具
- PyCharm - 智能 Python 集成开发工具(用过⭐)
- Rider - 快速且强大的跨平台 .NET IDE
- RubyMine - 最智能的 Ruby 与 Rails IDE
- WebStorm - 最智能的 JavaScript IDE
.NET
- ReSharper - 适用于.NET开发者的[Visual Studio](https://baike.baidu.com/item/Visual Studio/539453?fromModule=lemma_inlink)扩展
- dotCover - .NET 单元测试运行程序和代码覆盖率工具
- dotMemory - .NET[ 内存](https://baike.baidu.com/item/ 内存/103614?fromModule=lemma_inlink)分析器
- dotPeek - 免费 .NET 反编译器和程序集浏览器
- dotTrace - .NET[ 性能分析](https://baike.baidu.com/item/ 性能分析/5621447?fromModule=lemma_inlink)器
团队工具
Space - 集成的团队环境
TeamCity - 安装即用的强大持续集成工具
YouTrack - 为敏捷团队打造的项目管理工具
[Hub ](https://baike.baidu.com/item/Hub /703984?fromModule=lemma_inlink)- YouTrack、[TeamCity ](https://baike.baidu.com/item/TeamCity /3230218?fromModule=lemma_inlink)和 Upsource 的连接器
编程语言
- Kotlin - 一个用于现代多平台应用的静态编程语言 。Kotlin可以编译成Java字节码,支持在JVM上运行;也可以编译成JavaScript,方便在没有JVM的设备上运行。Kotlin已正式成为Android官方支持开发语言。
Linux
- Vim + GCC⭐
GCC的安装:如何在 Ubuntu 20.04 上安装 GCC(build-essential)-阿里云开发者社区 (aliyun.com)
1 |
|
编辑器:Vim:Vim|Murphy
编译器:gcc/g++:Linux GCC简明教程(使用GCC编写C语言程序) (biancheng.net)
调试器:gdb:Ubuntu1804下安装gdb与使用 - michaelchengjl - 博客园 (cnblogs.com)
1 |
|
1 |
|
Linux上简单的C/C++程序是编写与运行我还会一点点,但程序复杂了,运行报错我看不懂了,需要调试器gbd的参与了,那这个时候我也凉凉了,因为我也不怎么会。还是那句话,我现在主要用到编程语言并不是C,很多复杂的东西我也不会😥😭。
- 使用VScode SSH 连接云服务器 ⭐
Connect over SSH with Visual Studio Code
这是我目前使用Linux系统最常用的方法了!
参考资料
VS2019提示scanf不安全问题 - Townmacro - 博客园 (cnblogs.com)
VScode 看这一篇就够了_Jack_joker的博客-CSDN博客_vscode
MinGW-w64简介_itas109的博客-CSDN博客_mingw64是什么
MinGW 是什么?_大儿童梦里花开的博客-CSDN博客_mingw是什么
最适合C/C++语言初学者使用的编译软件—–Dev-C++的详细下载安装教程!
查看C&C++编译器所实现的标准
Language Standards
Language standards requires the existence of pre-defined macros.
Name | Macro | Standard |
---|---|---|
C89 | __STDC__ |
ANSI X3.159-1989 |
C90 | __STDC__ |
ISO/IEC 9899:1990 |
C94 | __STDC_VERSION__ = 199409L |
ISO/IEC 9899-1:1994 |
C99 | __STDC_VERSION__ = 199901L |
ISO/IEC 9899:1999 |
C11 | __STDC_VERSION__ = 201112L |
ISO/IEC 9899:2011 |
C18 | __STDC_VERSION__ = 201710L |
ISO/IEC 9899:2018 |
C++98 | __cplusplus = 199711L |
ISO/IEC 14882:1998 |
C++11 | __cplusplus = 201103L |
ISO/IEC 14882:2011 |
C++14 | __cplusplus = 201402L |
ISO/IEC 14882:2014 |
C++17 | __cplusplus = 201703L |
ISO/IEC 14882:2017 |
C++/CLI | __cplusplus_cli = 200406L |
ECMA-372 |
DSP-C | ISO/IEC JTC1/SC22 WG14/N854 | |
EC++ | __embedded_cplusplus |
Embedded C++ |
C
年份 | C标准 | 通用名 | 别名 | 标准编译选项 | GNU扩展选项 |
---|---|---|---|---|---|
1972 | Birth C | - | - | - | - |
1978 | K&R C | - | - | - | - |
1989-1990 | X3.159-1989, ISO/IEC 9899:1990 | C89 | C90, ANSI C, ISO C | -ansi, -std=c90, -std=iso9899:1990 | -std=gnu90 |
1995 | ISO/IEC 9899/AMD1:1995 | AMD1 | C94, C95 | -std=iso9899:199409 | - |
1999 | ISO/IEC 9899:1999 | C99 | - | -std=c99, -std=iso9899:1999 | -std=gnu99 |
2011 | ISO/IEC 9899:2011 | C11 | - | -std=c11, -std=iso9899:2011 | -std=gnu11 |
2018 | ISO/IEC 9899:2018 | C18 | - | -std=c18, -std=iso9899:2018 | -std=gnu18 |
C++
年份 | C++标准 | 通用名 | 别名 | 标准编译选项 | GNU扩展选项 |
---|---|---|---|---|---|
1978 | C with Classes | - | - | - | - |
1998 | ISO/IEC 14882:1998 | C++98 | - | -std=c++98 | -std=gnu++98 |
2003 | ISO/IEC 14882:2003 | C++03 | - | -std=c++03 | -std=gnu++03 |
2011 | ISO/IEC 14882:2011 | C++11 | C++0x | std=c++11, std=c++0x | std=gnu++11, std=gnu++0x |
2014 | ISO/IEC 14882:2014 | C++14 | C++1y | std=c++14, std=c++1y | std=gnu++14, std=gnu++1y |
2017 | ISO/IEC 14882:2017 | C++17 | C++1z | std=c++17, std=c++1z | std=gnu++17, std=gnu++1z |
2020 | to be determined | C++20 | C++2a | -std=c++2a | std=gnu++2a |
C编译器的标准
1 |
|
C++编译器的标准
1 |
|
gcc/g++
gcc发展到今天已经不单单可以编译C语言了,还可以编译C++、Java、Object-C等多种其他语言
有一种说法是GCC的全名是GNU Compiler Collection(GUN 编译器集合),而gcc是GCC中用于编译c语言的编译器
事实上,gcc看起来并不像是一个编译器,而像一个调度器,针对于不同的文件调用不同编程语言的编译器
对于后缀为*.c的文件,gcc把它当作是C语言程序源代码,而g++当作是C++程序源代码
对于后缀为*.cpp的文件,gcc和g++都会当作是C++程序源代码
使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL,所以再使用gcc编译C++程序是有时会报错
在用gcc编译C++文件时,为了能够使用STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价
据说g++会调用gcc,对于C++代码,因为gcc命令不能自动和C++程序使用的库联接,所以通常用g++来完成链接
需要注意的是,虽说g++会调用gcc,对于*.c文件来说,编译出来的可执行文件也不一样,因为gcc会当成C语言程序编译,而g++调用的gcc会把它当做C++语言程序来编译,这或许就能解释为什么用g++就可以编译所有C/C++的程序,还要有gcc的存在(就我测试来看,同样的C语言代码,g++编译出来的程序体积要大一些)
C语言的标准变化
C的标准化过程
C语言自诞生到现在,期间经历了多次标准化过程,主要分成以下几个阶段:
Traditional C
此时的 C 语言还没有标准化,来自“C Programming Language, First Edition, by Brian W. Kernighan, Dennis M. Ritchie. Prentice Hall PTR 1978”的 C 描述可算作“正式”的标准,所以此时的 C 也称为“K&R” C。
期间 C 语言一直不断的发生细微的变化,各编译器厂商也有自己的扩展,这个过程一直持续到20世纪80年代末。
C89
考虑到标准化的重要,ANSI(American National Standards Institute)制定了第一个 C 标准,在1989年被正式采用(American National Standard X3.159-1989),故称为 C89,也称为 ANSI C。
该标准随后被 ISO 采纳,成为国际标准(ISO/IEC 9899:1990)。
C89 的主要改动:
- 定义了 C 标准库;
- 新的预处理命令和特性;
- 函数原型(prototype);
- 新关键字:const、volatile、signed;
- 宽字符、宽字符串和多字节字符;
- 转化规则、声明(declaration)、类型检查的改变。
C95
这是对 C89 的一个修订和扩充,称为“C89 with Amendment 1”或 C95,严格说来并不是一个真正的标准。
C95 的主要改动:
- 3个新标准头文件:iso646.h、wctype.h、wchar.h;
- 一些新的标记(token)和宏(macro);
- 一些新的 printf/scanf 系列函数的格式符;
- 增加了大量的宽字符和多字节字符函数、常数和类型。
C99
1999年,在做了一些必要的修正和完善后,ISO 发布了新的 C 语言标准,命名为 ISO/IEC 9899:1999,简称“C99”。
C99 的主要改动:
- 复数(complex);
- 整数(integer)类型扩展;
- 变长数组;
- Boolean 类型;
- 非英语字符集的更好支持;
- 浮点类型的更好支持;
- 提供全部类型的数学函数;
- C++ 风格注释(
//
)。C11
2007 年,C语言标准委员会又重新开始修订C语言,到了 2011 年正式发布了 ISO/IEC 9899:2011,简称为 C11 标准。
C11 标准新引入的特征尽管没 C99 相对 C90 引入的那么多,但是这些也都十分有用,比如:字节对齐说明符、泛型机制(generic selection)、对多线程的支持、静态断言、原子操作以及对 Unicode 的支持。
C17
C17(也被称为为 C18)是于2018年6月发布的 ISO/IEC 9899:2018 的非正式名称,也是目前(截止到2020年6月)为止最新的 C语言编程标准,被用来替代 C11 标准。
C17 没有引入新的语言特性,只对 C11 进行了补充和修正。
C2x
下一个版本的 C 标准,预计将于2022年12月1日完成。
有许多人提出想为 C 语言添加面向对象的特性,包括增加类、继承、多态等已被 C++ 语言所广泛使用的语法特性,但是最终被委员会驳回了。因为这些复杂的语法特性并不符合 C 语言的设计理念以及设计哲学,况且 C++ 已经有了这些特性,C 语言无需再对它们进行支持。