C语言做为面向过程的高级程序设计语言,可以轻松的实现自顶向下的规划、结构化编程和模块化设计,这样使得程序结构更加简洁,可扩展性强以及更加容易维护。php
并且C语言有着高效(执行速度快)、功能强大(嵌套汇编)以及可移植性(标准库可移植)、功能强大等优势,并且也存在着对系统平台库依赖严重,因为编程风格自由,经验不足也会容易致使出错,编写代码实现周期长,一样的代码在不一样的操做系统(或者编译器)下可能会有不一样的表现等缺点。html
C语言偏向硬件驱动、操做系统、底层应用(数据库、编译器)、嵌入式应用开发、游戏引擎等应用场景。java
硬件驱动的绝大部分实现是由C语言和汇编语言实现的。
主流操做系统(Unix,Linux,macOS,Windows,Android,iOS)的底层实现都是由C语言和部分汇编实现的。
C++,Java,Python,Swift的编译器或者解释器都是由C语言实现的。
Git,Nginx,Redis,MySQL,Apache,Linux Kernel都是使用C语言实现的,并且都是开放源代码的,大部分代码能够在GitHub中获取到,能够经过阅读源码提高本身的设计和编码能力。linux
HelloWorld是学习一门编程语言的入门程序,若是你能独立编写并运行HelloWorld,那么就意味着迈入了编程的大门了。c++
Visual Studio Code是微软推出的一款开源、跨平台(Windows,Ubuntu,macOS)的编辑器,这里使用它来编写C语言的源代码,固然除了编写C代码以外,还能够用来编写C++,Java,Python,Go,JavaScript,PHP程序等等。程序员
为何首先要使用Visual Studio Code来编写第一个C程序呢,由于Visual Studio Code只是一个编辑器,用于编写源码,并不提供编译或者解释运行程序的功能。
经过它来对比以前介绍的IDE,体验下使用IDE开发程序带来的好处,也有利于理解IDE背后的相关机制。web
在使用Visual Studio Code以前首先去官网下载
shell
而后傻瓜一键式安装,安装完成之后启动Visual Studio Code会看到启动界面。
数据库
关于Visual Studio Code的详细使用能够参考官方提供的文档。编程
1.在系统的D盘下建立目录vs_code\c用于存放C语言的源程序(即C代码)
2.在Visual Studio Code中将D:\vs_code\c目录添加到工做区的文件夹
选择D:\vs_code\c文件夹做为Visual Studio开发C程序的工做区
3.在工做区D:\vs_code\c目录下建立源文件helloworld.c,C语言的源文件都是以.c结尾的,并编写如下内容
#include <stdio.h>
int main(int argc, char *argv[]){
printf("Windows10 1903 & Visual Studio Code Hello World With C \n");
return 0;
}
当源文件编辑好完成之后,须要安装和配置gcc,由于Visual Studio Code并无提供编译C程序的功能。
若是你以前已经下载安装过Qt,那么恭喜不用额外安装gcc,由于Qt已经集成了编译器。
只须要将gcc在Qt的bin目录: C:\Qt\Qt5.13.0\Tools\mingw730_64\bin 添加至PATH环境变量便可。
当在终端上执行gcc命令时系统会从该目录寻找gcc对应的可执行程序gcc.exe。
当gcc的PATH环境变量配置成功以后,即可以打开命令提示符(即终端),输入gcc -v即可查看gcc版本信息
而后在终端上运行a.exe,程序会将字符串Windows10 1903 & Visual Studio Code Hello World With C输出到终端上。
若是想要改变编译生成的可执行文件名称,使用gcc时可使用-o选项实现
刚才在使用gcc编译helloworld时一次性编译连接生成了可执行文件(例如helloworld.exe),而实际上gcc在编译程序时要经历预处理、编译、汇编、连接四个步骤,每一个步骤gcc都提供了对应的选项(连接除外),而且每一个步骤生成的文件后缀名也是不同的。
这里编写源文件gcc_compile_option.c,用于测试gcc的各个编译选项,若是想要查看gcc命令的全部选项,可使用gcc --help
查看全部选项及其说明
#include <stdio.h>
#define PI 3.141592 //宏定义
int main(int argc, char *argv[]){
printf("PI = %f \n",PI);
return 0;
}
gcc预处理命令案例
gcc -E gcc_compile_option.c -o gcc_compile_option.i
这里预编译会将头文件stdio.h的内容复制到gcc_compile_option.i头文件中,而且将使用#define PI 3.141592的宏进行替换,所以最后运行程序时会看到终端上输出PI =3.141592
gcc编译案例
gcc -S gcc_compile_option.i -o gcc_compile_option.s
gcc汇编案例
gcc -c gcc_compile_option.c -o gcc_compile_option.o
gcc 连接案例
gcc gcc_compile_option.o -o gcc_compile_option.exe
目前主流的操做系统(Windows,Linux,macOS)都有完善的C语言集成开发环境,用于编辑、编译、调试、打包部署C程序。
操做系统 | 开发工具 |
---|---|
Windows10 1903 | Visual Studio 2019 |
macOS10.15 | XCode10.3 |
Ubuntu18.04 | QT5.13 |
Windows做为世界上最流行的桌面操做系统,当前最新版本为Windows10 1903,VisualStudio做为Windows上最强大的集成开发环境,能够开发Windows软件,游戏,Web应用等等,最新版本为VisualStudio2019 16.2.2。
XCode
除此之外还有些跨平台的C/C++ 开发工具,例如来自Jetbrains公司的CLion也能够用来编写C/C++程序。
CLion
关于IDE的安装以及使用,它们的官网都提供了详细的教程,同窗们能够自行去查阅。
C语言学习过程当中会使用Windows10 1903+Visual Studio 2019做为主力开发环境,若是没有特别的说明,默认的环境就是Windows10 1903和Visual Studio 2019。
建立新项目
选择基于C++的空项目
配置新项目
设置项目名称为c-core-foundational,
项目路径位于d:workspace\c\visualstudio2019,
解决方案名称为c-core。
Visual Studio 2019中一个解决方案会有多个项目。
而后编辑源文件
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
system("pause");
return 0;
}
此段程序是调用了跨平台的输入输出函数实如今控制台输出Windows10 1903 & Visual Studio 2019 Hello World With C 并换行,而后等待用户输入任意键(一般习惯按回车键)后程序退出。
虽然该程序十分简单,可是是C语言中可以运行的最小程序。后面编写的程序都是在该基础之上扩展的。
C语言中以#开头的表示编译时预处理阶段须要处理的。
由于在main函数中使用了printf函数,可是该函数的声明是在标准输入输出文件stdio.h头文件中。所以须要使用#include <stdio.h>
将其包含在源文件helloworld.c中,该文件位于系统目录 C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\stdio.h
而该函数的实如今系统库文件中。
若是想要查看程序依赖了哪些库文件,Ubuntu下可使用ldd命令查看
std表示跨平台的,全部以std开头的头文件中声明的函数都是能够跨平台(windows,linux,macOS)使用。
stdio表示标准输入输出,printf函数就是用于输出,能够将""包含的内容数据输出到控制台,文件甚至是网页。而输入函数有scanf,用于读取键盘的输入,实现程序的交互。该函数后期再介绍详细使用。
若是想要在Visual Studio中查看系统提供的函数的定义,能够选中函数,而后按快捷键F12即可查看,而返回可使用Ctrl+-实现。
为了深刻理解#include的做用,这里编写一段程序。
首先在c-core-foundational的头文件建立和源文件同样目录的筛选器net\ittimeline\c\core\foundational\object
而后定义头文件include.h
而后将以前编写的源文件helloworld.c的内容复制到include.h头文件中
并在源文件的net\ittimeline\c\core\foundational\object\目录下建立源文件include.c,该源文件中只须要使用#include <include.h>
包含以前编写的头文件便可。
而后运行程序,若是发现以下错误
1>include.obj : error LNK2005: _main 已经在 helloworld.obj 中定义
是由于在Visual Studio 中,解决方案的一个项目只能有一个main函数,若是包含了多个源文件,把其余源文件的main函数重命名成其余函数便可。
而后再次运行程序,程序结果和以前的helloworld运行结果是同样的。
main函数是c/c++/java程序的入口函数,有且只能有一个,当程序执行时系统会自动调用惟一的main函数,程序从main函数开始执行。若是程序中编写了其余的函数,其余的函数应该被main函数调用才会获得执行。
例如定义一个返回两个整数相加的函数add,而后想要执行该函数,则必须在main函数调用。
#include <stdio.h>
#include <stdlib.h>
//自定义函数,返回两个整数相加的结果
int add(int left,int right) {
return left + right;
}
int main(int argc, char* argv[]) {
int left = 10;
int right = 20;
//调用add函数,并定义变量保存结果
int result =add(left,right);
printf("%d + %d = %d",left,right,result);
system("pause");
return 0;
}
main函数左边的的int表示函数的返回类型为整数
main函数右边的()表示函数的参数,经过传递参数,将外部数据传入函数内部处理。
{}表示函数的函数体,函数具体作什么事情,都写在{}内,{}是成对出现的。
main函数中的 printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
表示将Windows10 1903 & Visual Studio 2019 Hello World With C输出到控制台,\n表示换行。而;表示语句结束,C语言中的每条语句都要使用;表示结束,不然程序会编译错误。
return 0 表示返回给系统0,并结束main函数,0表示main函数正常退出。
return以后的代码都不会执行。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
system("pause");
return 0;
printf("Windows10 1903 & Visual Studio 2019 Hello World With C again \n");
}
运行上面的程序,Windows10 1903 & Visual Studio 2019 Hello World With C again不会获得输出。
注释是用于描述程序的功能,为了便于程序后期的维护,在开发过程当中应该添加适量的注释,编译器在预编译时会删除注释,因此注释的内容不会影响程序的结果。
C语言中支持的注释包含单行注释(//
)和多行注释(/**/
)两种,单行注释顾名思义就是注释一行,多行注释能够注释多行,须要注意的是多行注释不可以嵌套使用,不然会发生编译错误。
增长单行注释和多行注释后的helloworld程序
#include <stdio.h>
#include <stdlib.h>
/* main函数左边的int是函数的返回值,右边()的内容表示函数的参数,外部数据经过函数的参数传递到函数的内部处理。 {}表示函数的函数体,也就是函数执行的全部内容都包含在{}中,它是成对出现的。 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/10/17 */
int main(int argc, char* argv[]) {
// printf函数是系统自带的函数,用于将""包含的字符串按照指定的格式输出到终端,终端能够是控制台、网页或者是文件,目前是输出到控制台。
printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
//等待输入任意内容退出程序
system("pause");
return 0;
}
主流的操做系统(Windows,Linux(Ubuntu),MacOS)及大多数应用程序都提供了基于命令行和图形化界面两种交互方式,而移动端是采用手势触控、语音等进行交互。做为普通用户来说,图形化界面容易上手,并且交互效果更加直观。
可是做为一个程序员来说,应该去熟悉各个操做系统的命令行的使用,由于命令行相对图形化界面而言,绝大多数场景下使用更加高效。并且图形化界面本质是对命令行的封装,能用图形化界面实现的基本均可以采用命令行实现。并且在服务器端(CentOS,RedHat)基本上是不会安装图形界面。
Windows下想要使用命令,必须首先启动控制台。
Windows系统可使用快捷键Windows+r调出运行
后输入cmd,即可以进入Windows下的命令行终端
在启动Windows的终端(也称为控制台)以后,即可以运行命令了。若是你使用Windows做为开发平台,以下的命令你也许会常用到。
命令名称 | 功能描述 |
---|---|
dir | 列出当前目录列表 |
cd | 切换目录(只能在根盘符(例如C盘)内切换),cd /切换到磁盘的根目录 |
md | 建立目录 |
rd | 删除空目录 |
del | 删除文件 |
type | 显示文本文件内容 |
echo | 输出文本内容 例如echo %path% 查看系统环境变量 |
ping | 检测网络,例如ping baidu.com |
notepad | 记事本 |
calc | 计算器 |
mspaint | 画图 |
explore | 文件资源管理器 |
cleanmgr | 磁盘清理 |
desk.cpl | 分辨率设置 |
powercfg.cpl | 电源设置 |
regedit | 注册表编辑器 |
msconfig | 系统配置 |
mstsc | 远程链接 |
firewall.cpl | 防火墙 |
appwiz.cpl | 添加或修改程序 |
tasklist | 查看进程列表 |
taskkill /f /im process-name.exe | 关闭指定进程 |
netstat -ano|findstr "port" |
查看端口占用 |
msinfo | 系统信息 |
sticky notes | 便签 |
ipconfig | 查看ip |
winver | 查看windows版本 |
cls | 清除屏幕内容 |
exit | 退出终端 |
在终端上使用命令时还有些快捷键,例如Tab能够补全路径,上下键能够切换以前输入的命令。*
实现模糊匹配操做,例如 del *.txt
就能够删除 指定目录的全部文本文件。
若是想要获取更多的windows命令信息,能够在终端上输入help回车后会显示每一个命令的名称以及功能说明。
system函数用于C程序中调用各大操做系统的命令和应用程序,被调用的命令和应用程序以字符串的方式做为system函数的参数传入,实现读取用户输入的命令,并执行该命令。
在windows上运行该程序时能够传入notepad,calc等等实现程序调用。
而Linux和macOS上也有本身的命令能够提供给system函数来调用。
这里编写一个交互式程序:经过借助C语言的scanf函数读取用户在终端的命令,而后调用system函数来执行对应的命令。
若是你的开发环境不是Windows10 1903和Visual Studio 2019,能够删除#define _CRT_SECURE_NO_WARNINGS
。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 使用system函数调用各大操做系统的命令 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/10/17 */
int main(int argc, char* argv[]) {
// 提示用户输入执行的命令
printf("请输入须要执行的命令\n");
//定义字符串保存用户输入命令
char command[100] = {0};
//读取用户从键盘输入的命令字符串,并保存到command中
scanf("%s",command);
//执行命令
system(command);
system("pause");
return 0;
}
由于system函数位于stdlib.h头文件中,意味着它是一个能够跨平台使用的函数。
例如在Ubuntu下使用gedit命令调用文本编辑器
可是各大操做系统的命令和应用程序是不相同的,例如在Windows上使用system函数传递字符串参数"notepad"时能够打开记事本,而移植到了类Unix上则没法调用记事本。
在Visual Studio 2019中运行程序能够经过快捷键F5直接运行,也能够经过点击本地Windows调试器运行。
可是发如今运行helloworld后程序有闪退现象,即程序运行时打开了终端后当即退出,其缘由是程序运行是printf函数默认输出数据到终端,所以Visual Studio 2019开启了终端,printf输出数据完成之后,程序遇到return语句并退出,所以终端也会随之退出,由于弹出终端和退终端的时间很是短,全部感受有闪退现象。
为了解决这一问题,首先须要在源文件使用#include <stdlib.h>
包含标准库头文件,而后在main函数的最后一行加上system("pause")
,这样程序运行时不会当即退出,而是等到用户输入任意键(通常习惯按回车键)才会退出。
解决 helloworld在Visual Studio 2019运行的闪退问题
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
system("pause");
return 0;
}
再次运行程序时,在程序的末尾会输出一句请按任意键继续...
在平常使用Visual Studio 开发中会使用到以下经常使用的快捷键
快捷键名称 | 功能 |
---|---|
Ctrl+k,f | 自动格式化代码 |
Ctrl+k,c | 注释代码 |
Ctrl+k,u | 取消注释代码 |
Ctrl+F5 | 不调试运行 |
Ctrl+shift+b | 编译,不运行 |
F12 | 查看函数定义 |
ctrl+- | 退出函数定义 |
F5 | 调试运行 |
F11 | 逐语句(遇到函数跳到函数内部逐语句执行) |
F10 | 逐过程 (不会进入函数内部,可是函数会被调用) |
Shift+F11 | 跳出 |
在后期编写程序时,经验不足的开发人员一般会遇到两种错误:编译错误和运行时错误,编译错误一般是编写的程序不知足编译器的语法规范,而运行时错误则是程序运行时发生的错误,想要排查程序运行时的错误,就须要使用IDE提供的调试功能。
在源文件debug.c中定义一个返回两个整数相乘的方法mul,而后在main函数中定义两个变量做为参数传入mul方法中,并调用两个整数相乘的方法,输出计算结果
#include <stdlib.h>
/* 定义两个整数相乘并返回 */
int mul(int source, int target) {
//打印输出传入mul方法的两个整数参数的值
printf("source = %d\n",source);
printf("target = %d\n", target);
return source * target;
}
/* Visual Studio 2019的调试 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/10/17 */
int main(int argc, char* argv[]) {
//定义两个变量
int source = 12;
int target = 12;
//调用两个整数相乘的方法,并将计算的结果保存到整数变量result中
int result = mul(source, target);
printf("result = %d \n",result);
system("pause");
return 0;
}
在调试程序前首先须要下断点,可使用快捷键F9下断点或者取消断点
而后使用F5调试运行程序,程序会在以前下过断点的地方暂停(不管是逐语句仍是逐过程),此时能够在Visual Studio提供的自动窗口中观察变量的值
若是想要一行一行调试代码,可使用快捷键F11,当遇到函数时(例如这里的mul函数),会进入函数的内部一行一行执行,直到该函数结束为止。
若是调试时不想进入函数的内部,可使用快捷键F10,当程序中调用了其余函数时不会进入其余函数内部,可是函数会被调用。
若是调试时想要从一个断点跳到另一个断点,可使用shift+F11实现。
C4996是Visual Studio 2019提供的错误编号
首先明确下C4996错误出现错误的缘由:
Visual Studio 但愿用户使用Visual Studio提供的非标准库函数,可是程序员但愿使用标准库函数,由于标准库是能够移植的。
若是在Visual Studio中使用标准的库函数,就会引起C4996错误相似于这种提示:error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details
.这里的strcpy是标准的库函数,而在Visual Studio中使用这个函数引起了C4996错误。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 解决visual studio 2019 的C4996错误 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {
//定义一个字符串
char str[32] = "";
//将hi string 复制到str中
strcpy(str, "hi string");
printf("str = %s \n",str);
system("pause");
return 0;
}
那么如何解决问题呢?
方案1:在源文件的第一行定义宏#define _CRT_SECURE_NO_WARNINGS
方案2:在源文件的第一行定义#pragma warning(disable:4996)
解决Visual Studio 2019的C4996错误的两种方式
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 解决visual studio 2019 的C4996错误 error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {
//定义一个字符串
char str[32] = "";
//将hi string 复制到str中
strcpy(str, "hi string");
printf("str = %s \n",str);
system("pause");
return 0;
}
Visual Studio 2019提供了代码片断的功能,其做用就是配置代码片断后,能够经过输入指定的快捷键生成模板代码,这样能够大大提升开发效率。
在后期编写C程序中,须要反复使用到以下的代码片断
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {
return 0;
}
首先自定义代码片断文件MyCCode.snippet
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>MyCCodeTemplate</Title>
<Shortcut>mcct</Shortcut>
<Description>c的标准模板代码</Description>
<Author>Microsoft Corporation</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
<SnippetType>SurroundsWith</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Code Language="cpp">
<![CDATA[#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@version
*/
int main(int argc, char *argv[])
{
system("pause");
return 0;
}]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
而后选择Visual Studio 2019 菜单 工具->代码片断管理器
选择代码片断管理器的语言为C++,而后选中My Code Snippets
而后为导入的代码片断选择一个位置
导入成功
导入成功以后新建任意的C程序源文件,在源文件中输入快捷键mcct就能够生成以下的代码片断
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {
system("pause");
return 0;
}
想要了解代码片断的更多内容,请移步官网