持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情
1、 C语言入门介绍
1.1 什么是C语言?
来着百度百科对C语言的描述:
C语言是一门面向过程、抽象化的通用程序设计语言,广泛应用于底层开发。 C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括一些类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。 冯.诺依曼在1945年提出了现代计算机的若干思想,被后人称为冯.诺依曼思想,这是计算机发展史上的里程碑。自1945 年至今大多采用其结构,因此冯.诺依曼被称为计算机之父。他的体系结构计算机由运算器、控制器、存储器、输入设备、输出设备五大部件构成。 C语言拥有一套完整的理论体系经过了漫长的发展历史,在编程语言中具有举足轻重的地位。 c语言诞生于美国的贝尔实验室,由D.M.Ritchie以B语言为基础发展而来,在它的主体设计完成后,Thompson和Ritchie用它完全重写了UNIX,且随着UNIX的发展,C语言也得到了不断的完善。为了利于C语言的全面推广,许多专家学者和硬件厂商联合组成了C语言标准委员会,并在之后的1989年,诞生了第一个完备的C标准,简称“C89”,也就是“ANSI c”
1.2 C语言与其他编程语言的比较
C语言与C++、Java等面向对象编程语言有所不同。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。C语言描述问题比汇编语言迅速、工作量小、可读性好、易于调试、修改和移植,而代码质量与汇编语言相当。C语言一般只比汇编语言代码生成的目标程序效率低10%~20%。因此,C语言可以编写系统软件。
当前阶段,在编程领域中,C语言的运用非常之多,它兼顾了高级语言的汇编语言的优点,相较于其它编程语言具有较大优势。计算机系统设计以及应用程序编写是C语言应用的两大领域。同时,C语言的普适较强,在许多计算机操作系统中都能够得到适用,且效率显著。
总的来说,每种编程语言各有千秋,各有自己存在的价值;C语言是可以用来编写操作系统的贴近硬件的语言,所以,C语言适合开发那些追求运行速度、充分发挥硬件性能的程序。
记住:语言终究只是工具,算法才是核心,思路才是灵魂。
用任何编程语言来开发程序,都是为了让计算机做指定的事情,比如: 删除某些文件,下载一个文件,编写一个文档等等;而计算机的CPU只认识机器指令,所以,尽管不同的编程语言差异极大,最后都得“翻译”成CPU可以执行的机器指令。而不同的编程语言,做同样的一件事情,编写的代码量,差距也很大。
1.3 C语言的特点
(1)、语言,简洁,紧凑,使用方便灵活。C语言一共有32个关键字,9种控制语句,程序书写自由,压缩了一切不必要的成份。
(2)、运算符丰富。
(3)、数据类型丰富,具有现代语言的各种数据结构。
(4)、具有结构化的控制语句。
(5)、语法限制不太严格,程序设计自由度大。
(6)、C语言允许直接访问物理地址,能进行位(bit)操作,能实现汇编语言的大部分功能,可以直接对硬件操作。
(7)、生成目标代码质量高,程序执行效率高。C语言一般只比汇编程序生成的目标代码效率低10%-%20。
(8)、C语言编写的程序可移植性好,基本不用太多的修改就能在各种平台上运行。
1.4 C语言的应用现状
(1)、C语言是操作系统内核开发领域几乎是唯一开发工具,大部分操作系统是由C加上少量汇编语言开发的;比如:Linux、Windows、Vxworks、Unix。
(2)、在嵌入式领域占有绝对优势。
(3)、在网络服务器类相当大优势Apache、Oracle。
(4)、GUI应用领域、大型商用程序采用C的较多 。比如: Offices,SPSS,AutoCAD。
(5)、大规模、高性能计算、游戏开发以及一些传统的客户端软件和构件。
1.5 编写C语言代码推荐的编辑器
C语言是跨平台的编程语言,在windows系统、Linux系统下都可以学习,下面介绍学习C语言,编写C语言代码比较方便的一些工具软件。
(1) Visual Studio Code
Microsoft在2015年4月30日Build 开发者大会上正式宣布了 Visual Studio Code 项目:一个运行于 Mac OS X、Windows和 Linux 之上的,针对于编写现代 Web 和云应用的跨平台源代码编辑器。
下载地址: code.visualstudio.com/
图1-5-1
图1-5-2
(3) sublime text
Sublime Text 3是一款流行的代码编辑器软件,也是HTML和散文先进的文本编辑器,可运行在Linux,Windows和Mac OS X。也是许多程序员喜欢使用的一款文本编辑器软件。
下载地址: www.sublimetext.com/3
图1-5-4
二、Windows系统下搭建C语言学习环境
2.1 安装VSCode代码编辑器
Visual Studio Code是微软推出的跨平台源代码编辑器,编写各种编程语言代码都很方便。
下载地址: code.visualstudio.com/
图2-1-1
图2-1-2
安装包下载之后,直接鼠标双击运行。
图2-1-3
图2-1-4
图2-1-5
图2-1-6
图2-1-7
图2-1-8
图2-1-9
图2-1-10
软件安装之后下面设置 Visual Studio 支持中文语言
首先打开 Visual Studio 软件, 再按下 F1 或者 Shift + Ctrl + P:
然后在命令行输入 Configure Display Language
图2-1-11
选择安装语言选项。
图2-1-12
安装之后右下角有提示重启,点击重启即可。
图2-1-13
图2-1-14
软件安装之后,新建一个.c文件保存到指定目录下;这时候软件的右下角会提示安装 C/C++的扩展支持,点击安装即可。
下面介绍更改颜色vscode的颜色主题。
图2-1-15
图2-1-16
2.2 Mingw-w64编译器下载
VS Code只是一个编辑器,并不是IDE(集成开发环境);不含编译器(和许多其它功能),要编译C/C++程序,需要单独下载编译器。
在Windows 下一般使用Mingw-w64工具集,搭建 C 语言开发环境;
Mingw-w64提供在 Windows下的 C 语言开发环境,工具集包含了头文件、库、运行时和一些工具,支持64位开发,是 MinGW 的升级项目。
其实MinGW和MinGW-w64只是名字像,它们是两个不同的项目;MinGW本身已经很久没有更新了,故不推荐。
Vscode官方的说明与使用文档: code.visualstudio.com/docs/langua…
Window下MinGW离线安装包下载地址:
链接: pan.baidu.com/s/1vv8AkmRm… 提取码: 5m6k
注意: 这是win10_64位系统的MinGW。
图2-2-1
下载的压缩包名称: i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z
2.3 添加编译器路径到系统环境变量
将压缩包解压到指定目录下,推荐存放到C盘,在C盘创建一个名称为“MinGW”的目录。
图2-3-1
将gcc/g++可执行文件的路径添加到系统环境变量中。
图2-3-2
图2-3-3
图2-3-4
图2-3-5
图2-3-6
图2-3-7
图2-3-8
图2-3-9
2.4 测试编译器
打开vscode编写代码,写完代码在终端编译运行。
图2-4-1
图2-4-2
2.5 vs code 终端PowerShell介绍
Windows下Vs code的内置终端使用的就是PowerShell。
图2-5-1
PowerShell,从名字可以知道,他首先是一个shell,shell的意思就是和Linux的bash等一样、和原来的cmd一样就是在里边敲命令(可执行文件)使用;
而Power就意味他是一个功能强大的shell,从面向用户而言,个人觉得其功能强大体现在以下几方面:
(1) 微软态度。微软是真正的在推行PowerShell,包括Office等更多自家软件,底层都是调用PowerShell来实现。
(2) 兼容性cmd。PowerShell包含原先cmd的所有命令,原先命令使用形式不变,在是在其基础上添加命令。
(3) 对标Linux。PowerShell使用了Linux Shell的思想,也就是所有的系统操作、配置,都可以在shell中敲写命令实现。
(4) 统一的命令格式和自包含的文档。基于前3点我们即可以说PowerShell已可与Linux Bash等一较高下,如果再加上后发优势那就可以让人相信PowerShell可以成功。
当然powershell很好,但也有着其劣势:
(1)Linux和Windows系统本身定位的差异。Linux的免费稳定使其牢牢占据了服务器领域,Linux Shell命令是没有很多统一格式的;因此工程师们要费很大的劲去学习,而当Linux占据工程师的大部分精力并塑造完他们的习惯后,工程师们也许并没有那么多精神和动力去学powershell。
(2)来自Windows GUI的竞争。Windows上命令能干的事GUI也都能干也许效率慢一些,但普通用户可不想去黑漆漆的界面敲感觉不受控制的命令。
2.6 VSCode 中文输出乱码解决办法
文件 >> 首选项 >> 设置
搜索:
"files.autoGuessEncoding": false
改为:
"files.autoGuessEncoding": true
然后出去将.c代码文件改为GB2312编码保存,再使用VSccode打开即可。
图2-6-1
图2-6-2
三、栈空间和堆空间增长方向
示例代码: 验证堆空间和栈空间的增长方向
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
int main(int argc,char **argv)
{
//存放在栈空间
char a1;
char a2;
char a3;
char a4;
//
char *b1;
char *b2;
char *b3;
char *b4;
//申请堆空间
b1=malloc(1);
b2=malloc(1);
b3=malloc(1);
b4=malloc(1);
printf("a1=%#x\n",&a1);
printf("a2=%#x\n",&a2);
printf("a3=%#x\n",&a3);
printf("a4=%#x\n",&a4);
printf("b1=%#x\n",b1);
printf("b2=%#x\n",b2);
printf("b3=%#x\n",b3);
printf("b4=%#x\n",b4);
/*
栈空间: 大-->小 高地址-->低地址增长
a1=0xbfc1477f
a2=0xbfc1477e
a3=0xbfc1477d
a4=0xbfc1477c
堆空间:小-->大 低地址--->高地址增长
b1=0x8c78008
b2=0x8c78018
b3=0x8c78028
b4=0x8c78038
*/
return 0;
}
示例代码: 局部变量在内存里的数据摆放形式
![W0@4RQ~4}0BWRYZX6P7WM1.png
![%@45~5TOWL]XROO9{JXF(6O.png](p3-juejin.byteimg.com/tos-cn-i-k3…?)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
int main(int argc,char **argv)
{
//大端和小端的问题 单个空间大于1个字节才有这个概念。
//0x83 1000 0011 右边是低位 左边是高位
unsigned int a=0x12345678;
char *p=(char*)&a;
printf("%#x\n",*(p+0)); //0x78 低地址
printf("%#x\n",*(p+1)); //0x56
printf("%#x\n",*(p+2)); //0x34
printf("%#x\n",*(p+3)); //0x12 高地址
return 0;
}
示例代码: 根据栈空间特点提取可变形参列表里的数据
栈空间特点(压栈、出栈): 先入后出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
void func(char *p,...);
int main(int argc,char **argv)
{
func("123","456","789");
return 0;
}
void func(char *p,...)
{
printf("%c",*(p+0));
printf("%c",*(p+1));
printf("%c",*(p+2));
p-=4;
printf("%c",*(p+0));
printf("%c",*(p+1));
printf("%c",*(p+2));
p-=4;
printf("%c",*(p+0));
printf("%c",*(p+1));
printf("%c",*(p+2));
}
示例代码:取字符串数据
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
void func(char *p,...);
int main(int argc,char **argv)
{
func("123","abcdef","1234567890");
return 0;
}
//"1234567890" "abcdef" "123"
void func(char *p,...)
{
int i;
for(i=0;i<3;i++)
{
printf("%c",p[i]);
}
printf("\n");
p-=7;
for(i=0;i<6;i++)
{
printf("%c",p[i]);
}
printf("\n");
p-=11;
for(i=0;i<10;i++)
{
printf("%c",p[i]);
}
printf("\n");
}