C语言学习记录(一)——工具选择


前言

今天开始自学C语言,希望不要半途而废!

不论是人类语言还是机器语言,语言都是一个需要多练习的东西。因此学习过程中要拿着编辑器边写代码、边运行,边学习。因此环境的选择和搭建十分重要。我的参考内容是一位博友推荐的笨方法学C。因此环境及工具的选择和书中一致。


一、环境准备

首先选择操作系统,再安装学习C语言必备的编译器。

1. 操作系统

参考书的作者介绍Linux是C语言运行的最佳环境,而我的电脑是Win10,因此选择安装虚拟机获得Linux环境。
今天发现在Win10上可以开启一个叫 Hyper-V 的应用,可以非常方便地安装虚拟机,它向用户隐藏了复杂的系统安装步骤,操作简单。具体VM安装步骤可以参照这篇文章
我选择了Ubuntu 18.04的虚拟系统。

2. 编译器

Ubuntu不提供C的编译环境,需要手动安装,常用的C语言编译器有gcc,但如果单独安装它会很麻烦。于是Ubuntu非常优秀地提供了build-essential软件包,安装后即可在Ubuntu中编译C程序。在Linux中安装软件包非常简单,可使用下面的命令:

$ sudo apt-get install build-essential

3. 文本编辑器

现在已经搭建好了运行C程序的环境,可是我们在哪里写代码呢?
(为了提升自己,不使用IDE进行编程)

在Linux中有很多可供选择的文本编辑器,我听说大神都用vim的,可是它用起来实在是不顺手。作为初级选手,我选择gedit,这款和普通的文档一样,可鼠标操作hhhh。而且gedit不需要安装,Ubuntu自带的。新建和打开文档的命令都是:

$ gedit ex1.c

二、Make、Makefile

1. C程序的运行?

如果我们写好了一个代码文件ex1.c,在命令行中如何将它运行起来呢?
这时需要使用“make”对源文件(即我们写出来的原始代码文件)进行编译,获得一个可执行目标文件后,直接调用该目标文件就可以运行源文件的程序。

步骤:

  • 编译获得可执行文件
$ make ex1
cc     ex1.c   -o ex1
// 或者执行:
$ CFLAGS="-Wall" make ex1
cc -Wall    ex1.c   -o ex1

上面的第二个命令,是指编译时显示出代码中存在的所有warning。

  • 运行可执行文件
$ ./ex1
// 显示输出结果

2. Make的进阶

现在我们只有一个源文件需要编译,直接在命令行里写make命令比较简单。但当我们面对一个庞大的项目时,需要对里面很多.c文件进行编译(每修改一次源码就需要重新编译)而且有时还需要添加可选参数,比如CFLAGS=“-Wall”。这时再使用命令行一个一个去编译就显得傻乎乎了,Makefile就派上了用场。

我们在源文件所在的路径下创建一个Makefile文件,在里面写需要的配置。

$ gedit Makefile

最简单的Makefile中,我们可以只配置make的运行环境,比如将CFLAGS=“-Wall”从命令行中拿掉,放到Makefile中。这样每次使用make编译时,不需要加CFLAGS="-Wall" ,它也会运行在添加了该选项后的环境下。

Makefile中的内容如下:

CFLAGS=-Wall -g
clean:
    rm -f ex1

我们再进行编译时,可以直接写成

$ make ex1
cc -Wall    ex1.c   -o ex1

关于Makefile的更多内容可以参看这篇文章,就可以大概对它的功能和用法有一个基本了解。

我认为Makefile在一个项目中非常重要,它为当前的项目提供了特定的编译要求以及依赖关系,通过它可以实现只用一个make就编译好整个项目。而且显然,它不能用于其他项目。

三、初遇Valgrind

我第一次见到Valgrind这个软件,参考书作者说这是非常有用的用来发现bug的软件。在
运行程序时,使用valgrind可以在显示结果中看到运行中的所有错误。据说它对于程序运行时内存的监控十分有效。

1. 安装Valgrind

请安装最新版本,不然会出现各种报错~

# 1) Download it (use wget if you don't have curl)
$ curl -O http://valgrind.org/downloads/valgrind-3.16.1.tar.bz2
# 2) Unpack it.
tar -xjvf valgrind-3.16.1.tar.bz2
# cd into the newly created directory
cd valgrind-3.16.1
# 3) configure it
./configure
# 4) make it
make
# 5) install it (need root)
sudo make install

编译的过程稍废时间,需要等待一会儿。

2. 使用方法

编译源文件后,直接使用valgrind运行目标文件。
下面的ex4.c文件中故意设置了一些错误(一个变量未初始化),因此在编译时出现了警告。使用valgrind运行时,会显示出现了哪些错误,并且能够定位到行。

$ make ex4
cc -Wall -g    ex4.c   -o ex4
ex4.c: In function 'main':
ex4.c:10: warning: too few arguments for format
ex4.c:7: warning: unused variable 'age'
ex4.c:11: warning: 'height' is used uninitialized in this function
$ valgrind ./ex4

下面就是用valgrind运行输出的结果:

==3082== Memcheck, a memory error detector
==3082== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==3082== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==3082== Command: ./ex4
==3082==
I am -16775432 years old.
==3082== Use of uninitialised value of size 8
==3082==    at 0x4E730EB: _itoa_word (_itoa.c:195)
==3082==    by 0x4E743D8: vfprintf (vfprintf.c:1613)
==3082==    by 0x4E7E6F9: printf (printf.c:35)
==3082==    by 0x40052B: main (ex4.c:11)
==3082==
==3082== Conditional jump or move depends on uninitialised value(s)
==3082==    at 0x4E730F5: _itoa_word (_itoa.c:195)
==3082==    by 0x4E743D8: vfprintf (vfprintf.c:1613)
==3082==    by 0x4E7E6F9: printf (printf.c:35)
==3082==    by 0x40052B: main (ex4.c:11)
==3082==
==3082== Conditional jump or move depends on uninitialised value(s)
==3082==    at 0x4E7633B: vfprintf (vfprintf.c:1613)
==3082==    by 0x4E7E6F9: printf (printf.c:35)
==3082==    by 0x40052B: main (ex4.c:11)
==3082==
==3082== Conditional jump or move depends on uninitialised value(s)
==3082==    at 0x4E744C6: vfprintf (vfprintf.c:1613)
==3082==    by 0x4E7E6F9: printf (printf.c:35)
==3082==    by 0x40052B: main (ex4.c:11)
==3082==
I am 0 inches tall.
==3082==
==3082== HEAP SUMMARY:
==3082==     in use at exit: 0 bytes in 0 blocks
==3082==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==3082==
==3082== All heap blocks were freed -- no leaks are possible
==3082==
==3082== For counts of detected and suppressed errors, rerun with: -v
==3082== Use --track-origins=yes to see where uninitialised values come from
==3082== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 4 from 4)
$

可以看到,它提示说:Conditional jump or move depends on uninitialised value(s),就是指存在变量未初始化,而且下面给出了具体在源文件中的第11行。

==3082==    by 0x40052B: main (ex4.c:11)

通过使用valgrind我们可以有效地找到错误原因,以及出错的位置,弥补命令行和IDE的功能效果差距。

作者说:
无论什么时候你运行C程序并且使它工作,都应该使用Valgrind重新运行它来检查。
一旦你的程序在Valgrind下不出现任何错误信息,应该就好了。

总结

我现在认为在学习一门语言之前,需要搭建好运行环境及平台,要边练边学,自己去查使用文档等。只有实操才能掌握语言!
补充一下在Linux下查看使用文档的命令:

$ man 3 库函数名
# 数字的含义:
1:Standard commands (标准命令)
2:System calls (系统调用)
3:Library functions (库函数)
4:Special devices (设备说明)
5:File formats (文件格式)
6:Games and toys (游戏和娱乐)
7:Miscellaneous (杂项)
8:Administrative Commands (管理员命令)
9:其他(Linux特定的), 用来存放内核例行程序的文档。

$ man name 
#相当于
$ man 1 name
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值