初识C语言

本文摘要

基本了解C语言的基础知识,对C语言有一个大概的认识。每个知识点就是简单认识,不做详细讲解,后期都会细讲。

注意

本文会讲解以上知识, 但是只是浅尝一下, 能让你看懂一些非常简单的C语言程序, C语言不止是这些内容, 后续的内容也很重要.

前提知识

无任何前提知识, 专为编程初学者而写.

什么是C语言

C语言简介

C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的
C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。

二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制
定了一套完整的美国国家标准语法,称为ANSI C,作为C语言最初的标准。 目前2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准是C语言的第三个官方标准,也是C语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程。

C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。

其编译器主要有ClangGCC、WIN-TC、SUBLIME、MSVC、Turbo C等。

标准 和 编译器的影响

  1. 可将C语⾔的标准理解为C语⾔说明书。但其并没有强制性约束⼒。
  2. 如果编译器不⽀持标准,我们即使使⽤标准中的语法仍然会报错
  3. 编译器版本也会影响程序。因此,编写程序之前要确定编译器版本。

如:微软拿到标准,认为有些标准不合理,不⽀持。
微软认为某些特性⾮常好,但标准中没有,微软可以修改标准,新增语法.\

常见的C/C++编译器

  1. Borland C++ 宝蓝公司
  2. Intel C++ 英特尔编译器
  3. MSVC 微软公司
  4. Clang JetBrains公司
  5. g++编译器(gcc是编译套件), Linux 默认使⽤的编译器. 对标准⽀持最好.
C语言系列使用的编译器与编译环境

  • 运行系统: Windows11
  • 开发环境: Visual Studio 2022(编译器为MSVC) . 极少数案例会使用GCC(用的时会特殊说明)

常见开发工具

跨平台性最好的是Clion

Clion的跨平台性是最好的, 因为不管在MacOS 还是Linux 还是Windows上, Clion 使用的编译器都是Clang. 但是该工具是收费的.

本系列使用的是 Visual Studio 2022 , 它的社区版本是免费的, 并且足够我们使用, 这里是安装教程.

第一个 C 语言程序: Hello World

安装 VS2022 并创建项目#创建项目

我在 源文件 这目录中创建 HelloWorld.c 文件, 名称前缀可以随意改, 但是文件后缀必须是 .c .

体验

在HelloWorld.c 文件中写如下内容:

#include <stdio.h>
int main()
{
    printf("Hello World!\n");
    return 0;
}
这段代码的意义

在屏幕上打印: Hello World

点击键盘上的 F5 运行程序.

或者点击这这两个按钮中的其中一个(这两个按钮是有差别的, 后续内容会讲到, 不会影响到前期的内容):
!Pasted image 20240604135908.png

以下是运行结果:
!Pasted image 20240604135214.png

运行后会出现一个黑框, 其中就有这个我们代码的运行结果.

详细解析

#include <stdio.h>
int main()
{
    printf("Hello World!\n");
    return 0;
}

C语言中main函数是程序的入口, 程序是从main函数的第一行开始执行的, main函数有且仅有一个.

#include : 引⼊头⽂件专⽤关键字。

printf()是一个库函数 是C语言编译器提供的一个现成的函数, 直接可以使用

注意事项

  • 程序中使⽤的所有的字符,全部是 “英⽂半⻆” 字符。
  • 程序中,严格区分⼤⼩写
  • 分号; 代表⼀⾏结束。不能使⽤ 中⽂分号 “”,必须是英⽂。

代码执行流程分析

写好的 .c 文件中的代码是文本信息, 这些代码是不能直接运行的, 那是如何成为程序的呢?
那就必须了解C语言的代码执行过程了.

完整的C语言运行,分为以下4步,在VS中我们直接运行,其实是把中间的步骤给省略了
!598

基础数据类型

什么是数据类型?

数据类型是编程中用来定义变量可以存储的数据种类的一种方式。就像我们在生活中有不同的容器用来存放不同的东西一样,编程中也有不同的数据类型来存放不同类型的数据。

  1. 整数(Integer):用来存储没有小数点的数字,比如:5, -3, 42
  • 例子:假设你有一个盒子用来存放年龄,你只能放整数进去,因为年龄没有小数点。
  1. 浮点数(Floating-point number):用来存储有小数点的数字,可以表示更精确的数值,比如:3.14, -0.001, 2.99792458e8(光速的近似值,科学记数法表示)。
    • 例子:如果你要计算一个圆的面积,你需要使用浮点数来存储圆的半径,因为半径可能有小数。
  2. 字符(Character):用来存储单个字母或者数字,比如:'a', '3', '@'
    • 例子:如果你要编写一个程序来检查用户输入的密码的第一个字符,那么你会用到字符类型。
  3. 布尔值(Boolean):用来表示真或假,只有两个值:TrueFalse
    • 例子:假设你有一个门禁系统,它只允许年龄大于18岁的人进入。系统会检查一个布尔值,如果年龄大于18,布尔值为True,门就会打开。

C语言有7中基础数据类型, 分别为:

char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数

C语言的基础数据类型按类型可以划分为:

C语言有没有字符串类型?

在C语言中,并没有专门的字符串类型,但是字符串是通过字符数组来表示的。通常,字符串在C语言中以字符数组的形式存在,并以空字符(null terminator,值为'\0')结尾,这表示字符串的结束。例如:

char myString[] = "Hello, World!";

关于字符串, 之后的内容会细讲.

为什么出现这么多的类型?

在C语言的广阔天地中,我们经常会遇到int、short、char, long ...等类型。这些类型就像是不同尺寸的容器,每个容器都有其特定的用途和携带能力。

若我们需要存放的东西很少, 却使用 long long 这个类型的容器进行存放, 那就会造成很大的空间浪费.

而在实际编程中, int , char , long long 这些基本类型就是我们的容器,
2 , 3 , 66 , 998 ,'c' "哈哈" 等信息就是可以存入相应容器的数据

请看一下代码

int main()
{
	long long big_box = 1;
	// 名叫 big_box 有 long long 这么大的空间, 但是它里面数据只放了1, 虽然可用, 但是有比较大的空间浪费

	int box = 2458568785;
	// 名叫 box 一个中号的容器, 但它容器里放的数据超出了它的容纳范围, 会数值溢出

	int small_box = 18266;
	// 名叫 box 一个小号的容器, 但它容器里放的数据在它的容纳范围内, 可用

	return 0;
}

看了以上代码, 那有一个问题, 我怎么知道每个类型它能容纳的大小是多少呢?

每种类型的大小是多少?

如何计算每个类型的大小?

每种数据类型,都有自己固定的占用内存大小和取值范围。具体展开讲解前,我们先来看下,C 语言提供的查看变量或类型占用内存大小的运算符,sizeof

  • 语法 1:sizeof(变量名)
int a = 10;  
  printf("%llu\n", sizeof(a));//sizeof(a) 获取 a 变量占用内存大小。可以用 printf 显示出来  
  // 查看 sizeof 返回的占用内存大小,需要使用 %llu 格式符
#include <stdio.h>
int main()
{
	printf("%d\n", sizeof(char));
	printf("%d\n", sizeof(short));
	printf("%d\n", sizeof(int));
	printf("%d\n", sizeof(long));
	printf("%d\n", sizeof(long long));
	printf("%d\n", sizeof(float));
	printf("%d\n", sizeof(double));
	printf("%d\n", sizeof(long double));
	return 0;
}

注意:存在这么多的类型,其实是为了更加丰富的表达生活中的各种值。

类型的使用:

char ch = 'w';
int weight = 120;
int salary = 20000;

变量和常量

生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等)
有些值是可变的(比如:年龄,体重,薪资)。

不变的值,C语言中用常量的概念来表示,变得值C语言中用变量来表示。

定义变量的方法

int age = 150;
float weight = 45.5f;
char ch = 'w';

变量的分类

#include <stdio.h>

int global = 2019;//全局变量

int main()
{
	int local = 2018;//局部变量
	//下面定义的global会不会有问题?
	int global = 2020;//局部变量
	printf("global = %d\n", global);
	return 0;
}

局部变量和全局变量总结:

上面的局部变量global变量的定义其实没有什么问题的!
当局部变量和全局变量同名的时候,局部变量优先使用。

变量的使用

#include <stdio.h>
int main()
{
	int num1 = 0;
	int num2 = 0;
	int sum = 0;
	printf("输入两个操作数:>");
	scanf("%d %d", &num1, &num2);
	sum = num1 + num2;
	printf("sum = %d\n", sum);
	return 0;
}
//这里介绍一下输入,输出语句
//scanf
//printf

变量的作用域和生命周期

作用域

作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的
而限定这个名字的可用性的代码范围就是这个名字的作用域。

  1. 局部变量的作用域是变量所在的局部范围。
  2. 全局变量的作用域是整个工程。

生命周期

变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段.

  1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
  2. 全局变量的生命周期是:整个程序的生命周期。

常量

语言中的常量和变量的定义的形式有所差异。
C语言中的常量分为以下以下几种:

#include <stdio.h>
//举例
enum Sex
{
	MALE,
	FEMALE,
	SECRET
};
//括号中的MALE,FEMALE,SECRET是枚举常量

int main()
{
	//字面常量演示
	3.14;//字面常量
	1000;//字面常量
	//const 修饰的常变量
	const float pai = 3.14f; //这里的pai是const修饰的常变量
	pai = 5.14;//是不能直接修改的!
	//#define的标识符常量 演示
	#define MAX 100
	printf("max = %d\n", MAX);
	//枚举常量演示
	printf("%d\n", MALE);
	printf("%d\n", FEMALE);
	printf("%d\n", SECRET);
	//注:枚举常量的默认是从0开始,依次向下递增1的
	return 0;
}

字符串+转义字符+注释

字符串

"hello bit.\n"

这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。
注:字符串的结束标志是一个\0 的转义字符。在计算字符串长度的时候\0 是结束标志,不算作字符串内容。

#include <stdio.h>
//下面代码,打印结果是什么?为什么?(突出'\0'的重要性)
int main()
{
	char arr1[] = "bit";
	char arr2[] = {'b', 'i', 't'};
	char arr3[] = {'b', 'i', 't', '\0'};
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	printf("%s\n", arr3);
	return 0;
}

转义字符

加入我们要在屏幕上打印一个目录: c:\code\test.c
我们该如何写代码?

#include <stdio.h>
int main()
{
	printf("c:\code\test.c\n");
	return 0;
}

实际上程序运行的结果是这样的:

运行结果

c:code est.c

image.png

总结