C语言入门(初识C语言)
前言
嘿嘿,当你点进这篇文章时,我想你一定对编程感兴趣,并且准备迈出学习它的第一步了吧?那么就让我们开始吧!编程是一件非常有趣的事情,希望你能够一直保持积极的心态面对它。我们就从C语言开始入门吧。接下来我将讲解C语言的基础知识。
什么是C语言?
C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易
的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语
言。
尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的
C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超
级电脑等作业平台。
二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制
定了一套完整的美国国家标准语法,称为ANSI C,作为C语言最初的标准。 [1] 目前2011年12月8
日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准是C语言的第三个官方标
准,也是C语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉
字编程。
C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。
其编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。
为什么选择C语言?
在明白为什么选择C语言之前,我们需要先了解一下计算机语言的发展历史
计算机语言的发展
一. 机器语言
第一代计算机语言称为机器语言。机器语言就是 0/1 代码。计算机只能识别 0 和 1。在计算机内部,无论是一部电影还是一首歌曲或是一张图片,最终保存的都是 0/1 代码,因为 CPU 只能执行 0/1 代码。那么这是不是就意味着我们编程一定要用 0/1 代码呢?
首先这么编写肯定是可以的,但是这样太麻烦,而且很不好理解,所以后来就出现了汇编语言。
二. 汇编语言
汇编语言就是将一串很枯燥无味的机器语言转化成一个英文单词。比如说:add 1, 2;
add 就是一个英文单词,这样看起来就稍微有一些含义了,即 1 和 2 相加。这个就是汇编语言。
如果直接用机器语言编写的话,这几乎是无法实现的。因为用机器语言太难记忆了,也没人能看得懂。所以后来就设计出了第二种语言,即将 0/1 代码翻译为英文单词,这些英文单词直接对应着一串 0/1 指令。这个就是汇编语言。
通过专门的软件就可以将这些英文单词转化成 0/1 代码并由计算机执行,这种专门起翻译的作用的软件叫作编译器。
这些英文单词和与它们对应的 0/1 代码之间的对应关系,以及语言的语法,在编写这个软件的时候就已经写在里面了。我们只要通过编译器就可以将这些都转化成 0/1 代码。这样大大方便了我们对程序的编写。
三. 高级语言
汇编语言之后又出现了第三代语言。第三代语言又叫“高级语言”。高级语言的发展分为两个阶段,以 1980 年为分界线,前一阶段属于结构化语言或者称为面向过程的语言如C语言、FORTRAN语言,后一阶段属于面向对象的语言,如C++、Python、、Java、C#等。
面向过程语言中最经典、最重要的就是C语言。C语言一直在用,因为C语言是计算机领域最重要的一门语言。但是C语言也有缺陷,它的缺陷只有在学完面向对象语言之后才能体会到。
高级计算机语言中的经典:C语言
C语言自上世纪70年代初诞生直到现在,凭借着它语言简洁、紧凑,使用方便、灵活 ;运算符丰富,语言的运算符包含的范围广泛;数据类型丰富;具有结构化的控制语句;程序设计自由度大;编写的程序可移植性好;代码质量高,程序执行效率高的特性,在最新的计算机语言排行榜上依然排进前三名。可见,C语言是一款经久不衰的语言。
数据来源:TIOBE网站
一直有一句话这样说:C语言乃是万物之本。所以我们从C语言开始学习是非常不错的选择。
那么,让我们开始C语言的学习吧!
初识C语言(正片开始)
一.第一个C语言程序(你好,C语言)
#include <stdio.h>
int main()
{
printf("Hello,World!\n");
printf("Hello,C!\n");
return 0;
}
程序运行结果如下:
看上去是不是很简单呢?现在就让我来介绍一下这些代码吧!
1.1 #include
include我们将它称为文件包含命令,它的作用就是将<>或者" "中的的文件包含到程序中。而stdio.h就是前面所说的“文件”,它的全名叫standard input output,“.h”是后缀名,表示它是一个头文件。那么这段代码的意思就是将stdio.h文件包含到本程序中。我们这里就先把它记住,以后的程序开头就以这个格式写上去就行了。
1.2 int main()
main函数(也叫主函数),是程序的入口,这里也是一样的,我们记住这个标准格式就行,在main函数下面有一对{}号,我们的代码就写在{}里面。需要注意的是,一个工程里只能有一个main函数!
1.3 printf
printf叫做格式化输出函数,用法就是将你想要输出的内容放入(" ")中,比如上面我们写的Hello,World!
当想要输出某个字符类型时,需要以这种格式打印 printf("数据类型\n",变量名);
,比如我已经定义了一个整型变量a,现在我想将它打印出来,那么就这样写:printf("%d\n",a);
你注意到了吗,我们在输出函数内容时,会添加一个**\n**,它是换行符,效果就是将光标移动到下一行。我们试着将上面写的代码去掉\n
#include <stdio.h>
int main()
{
printf("Hello,World!");
printf("Hello,C!");
return 0;
}
打印结果如下
这样你肯定理解了吧!
1.4 return 0
表示主函数返回的值为0,我们先记住这个格式,先不做深入了解。
1.5 小结
以上就是一个C语言程序的主要内容。我们以后写代码时就按照这个格式来写吧。有一些知识我们不必咬文嚼字,只需大概了解就行了,不会影响我们写程序的。
二.C语言数据类型
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数
这些是C语言的基本数据类型,如果想知道每一种数据类型所占空间的大小(单位是字节),我们可以使用sizeof运算符:
#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));
return 0;
}
程序打印结果:
三.C语言中的常量与变量
我们之前说了,编程可以用于解决生活中的问题。而生活中的事物有变化的也有不变的。
3.1 常量
常量:C语言中的常量就可以理解为不变的量,比如生活中的血型、性别、圆周率等。
- 字面常量
字面常量的意思就是已知的值,比如100,50等。 - const修饰的常变量
这是未用const修饰的变量:
使用const修饰过后:
这里我们还想修改a的值时,编译器报错了。这里我们解释如下:被const修饰过后的变量具有了常属性,其值不能再改变。 注意:a只是具有了常属性,但是它本质上还是一个变量。可以用数组的定义来证明:
- #define定义的标识符常量:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了。可以理解为编译器在预编译时将符号替换成常量的数值。举个例子吧:
在代码的第八行,MAX就是#define 定义的标识符常量,在预编译时,MAX会被替换成10。
- 枚举常量:可以一一列举出来的常量,C语言中使用enum关键字定义枚举常量。举例:
#include<stdio.h>
enum Sex
{
MALE,
FEMALE,
SECRET,
};
int main()
{
printf("%d\n", MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
return 0;
}
运行结果:
3.2 变量
- 变量的定义方法:
#include <stdio.h>
int main()
{
int a = 10;
float b = 6.66;
char c = 'a';
printf("a=%d\n", a);
printf("b=%f\n", b);
printf("c=%c\n", c);
return 0;
}
程序运行结果:
- 变量的分类
在C语言中变量有两类,局部变量和全局变量。
全局变量: 指在一个程序中对整个代码都有效的变量,定义在main函数之外。注意:由于全局变量的特性,我们甚至可以在一个工程中,跨文件使用同一个全局变量,所以它是很不安全的,一般情况下不建议使用。
局部变量: 指定义在{}内部的变量,它只在该区域内起作用。当一个程序中同时定义了相同名字的全局变量和局部变量时,采用局部优先的原则。举例:
- 变量的使用
变量的使用很简单,与生活中的数学不计较相似。这里我们以写一个可以计算两个整数相加减的程序为例子吧
#include<stdio.h>
int main()
{
int num1 = 20, num2 = 10;
int sum = 0, sub = 0;
sum = num1 + num2;
sub = num1 - num2;
printf("num1 + num2 = %d\n", sum);
printf("num1 - num2 = %d\n", sub);
return 0;
}
程序运行结果:
- 变量的作用域和生命周期
四. 转义字符和字符串
4.1 转义字符
转义字符其实我们早就见过了 printf("Hello world!\n");
这一段代码中的\n
就是一个转义字符,它叫换行符。
除了\n
,C语言中还有许多其他的转义字符:
感兴趣的话可以自己在代码中尝试。
4.2 字符串
字符串就是由" "
引起的内容,我们其实也见过它了, printf("Hello world!\n");
中的Hello world就是字符串。其中字符串最重要的一个知识点就是它的结束标志 ‘\0’。
看看以下代码:
#include<stdio.h>
int main()
{
char str1[] = { 'H','e','h','e','\0' };
char str2[] = { 'H','e','h','e' };
char str3[] = "Hehe";
printf("%s\n", str1);
printf("%s\n", str2);
printf("%s\n", str3);
return 0;
}
程序运行结果:
可见,字符串的结束标志为’\0’,在C语言中以char str[]="Hehe";
定义字符串,会在最后自动加上’\0’。而如果以char str1[] = { 'H','e','h','e','\0' };
这个形式定义字符串的话,切记要手动添加一个\0。否则打印出来的会是随机值,因为编译器只找\0,找到了\0它就认为字符串结束了,否则就会一直打印,直到内存中出现了\0。
4.3 注释
当我们写的程序越来越复杂时,定义了很多的变量,如果没有注释的话,我们过一段时间再回来读程序的时候会十分困难;或者是当我们写错了程序时,但是又不行删除写的代码,也可以用到注释。C语言提供了两种注释风格:
- C语言的注释风格:/* xxxxxx*/
缺点:不能嵌套注释 - C++的注释风格://xxxxx
既可以注释一行,也可以注释多行
五. 选择语句
生活中我们经常会遇到选择的问题, 举一个例子:我们该好好学习吗?接下来就该选择了,如果好好学习,就会得到一个好工作,否则,就没有好工作,回家卖红薯。 接下来,我们用图解和代码的形式把这段话描述出来。
#include <stdio.h>
int main()
{
int i = 0;
printf("请选择: (1.好好学习,0.摆烂)\n");
scanf("%d", &i);
if (i == 1)
{
printf("好offer!高薪资!\n");
}
else
{
printf("回家卖红薯。。。\n");
}
return 0;
}
程序运行结果:
C语言中的选择语句有if,else语句和switch语句,这里我们先介绍if,else语句。
六. 循环语句
生活中有很多事情需要我们日复一日的去做,这就是循环。C语言中提供了三种循环语句,while、for、do…while。
这里我们先介绍while循环。举一个例子:我们学习编程,每天写代码,当代码量达到一万行时就拿到好offer。接下来我们用C语言描述一下它:
#include <stdio.h>
int main()
{
int i = 0;
while (i<10000)
{
printf("%d行\n", i);
i++;
}
printf("写了一万号代码了,得到好offer!\n");
return 0;
}
七. 函数
7.1 自定义函数
在我们写代码的过程中,一个功能可能会用到很多次(比如计算两个数的和),那么我们可以把这一段代码模块化,以后想计算两个数的和时,就不需要自己重新写一遍这个代码了,直接调用这个函数就可以。接下来我们用两个模式写这段代码,第一个是一般写法,第二个是写成函数的形式。
- 一般写法
#include <stdio.h>
int main()
{
int num1 = 0, num2 = 0;
int sum = 0;
printf("请输入两个整数: \n");
scanf("%d %d", &num1, &num2);
sum = num1 + num2;
printf("sum = %d\n", sum);
return 0;
}
- 写成函数
#include <stdio.h>
int Add(int x, int y)
{
int sum = x + y;
return sum;
}
int main()
{
int num1 = 0, num2 = 0;
int sum = 0;
printf("请输入两个整数: \n");
scanf("%d %d", &num1, &num2);
sum = Add(num1, num2);
printf("sum = %d\n", sum);
return 0;
}
程序运行结果(两个代码的结果是一样的):
函数的特点就是可以简化代码,并且提高代码复用能力。
7.2 C语言库函数
说到库函数,我们不应该陌生,在前面写到的printf
就是C语言中的一个库函数,格式化输出函数。需要注意的是:在使用库函数之前,必须包含其头文件,比如我们想使用printf
函数,就包含了stdio.h
头文件。
想要了解更多的库函数,可以访问C++官网:cppreference.com
库函数的简单分类:
八. 数组
如果要连续存多个数据,该如何存?
C语言中给了数组的定义:一组相同类型元素的集合
8.1 数组的定义
int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素
8.2 数组的下标
如果我们要找到数组中的某个元素,比如第i
个元素,我们直接写arr[i]
可以吗?
注意了,这个写法是错误的!
C语言规定:数组的每个元素都有一个下标,下标是从0开始的。
如果数组10个元素,下标的范围是0-9
如果想打印该数组,需要用到循环,请看代码:
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
while (i < 10)
{
printf("arr[%d] = %d\n", i, arr[i]);
i++;
}
return 0;
}
程序运行结果:
九. C语言中的操作符
9.1 算术操作符
就是数学中的算术运算符:+,-,*,/,%。其中需要额外注意的是除法运算和%取模运算。请看代码:
9.2 移位操作符,位操作符,赋值操作符
- 移位操作符
>>(右移操作符), <<(左移操作符),作用分别是将目标的数值转换成二进制后,对二进制进行移位。举例:
右移操作符也是同理 - 位操作符:
&按位与 |按位或 ^按位异或
这三个都是进行的二进制位操作,这里我们先认识一下,之后进阶再介绍。
-赋值操作符
= += -= *= /= &= ^= |= >>= <<=
拿+=举例子吧,比如 a+=10;
这段表达式我们翻译一下就是a=a+10;
其他的也是同理的。
9.3 其他操作符
单目操作符 | 作业 |
---|---|
! | 逻辑反操作 |
- | 取负 |
+ | 取正 |
& | 取地址 |
sizeof | 求操作数的类型长度(单位是字节) |
~ | 对一个数的二进制按位取反 |
- - | 前置、后置- - |
++ | 前置、后置++ |
* | 解引用操作符 |
(数据类型) | 强制类型转换‘ |
项目关系操作符 | 作用 |
---|---|
> | 测试大于 |
< | 测试小于 |
>= | 测试大于等于 |
<= | 测试小于等于 |
== | 测试等于 |
!= | 测试不等 |
- 逻辑操作符
&&:逻辑与;
||:逻辑或。 - 条件操作符
exp1 ? exp2 : exp3;
举例:
- 逗号表达式
格式:exp1, exp2, exp3, …expN
- 下标引用、函数调用和结构成员
[] () . ->
十. 常见关键字
C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的。
我们先介绍几个,之后的慢慢了解。
10.1 typedef
typedef 顾名思义是类型定义,这里应该理解为类型重命名。
举例子:
十一. #define 定义常量和宏
请看例子:
十二. 指针
在了解指针之前,我们得先了解一下内存
什么是内存?
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。
所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。
如何取出变量的地址呢?
我们之前讲到的&
操作符就是干这个的:
如果我们想把&a,即a的地址存起来该怎么做呢?
这时指针就是我们想要的工具了。
#include <stdio.h>
int main()
{
int a = 10;
int* pa = &a;
printf("%p", pa);
return 0;
}
注意:不同类型变量的地址,应该用与之相对应的指针来存储。
到这了,我们不难发现,其实指针本质上就是也是一种变量,只不过是专门用来存储地址的。
那么变量应该也有大小吧?
我们不妨用sizeof试试?
#include <stdio.h>
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
printf("%d\n", sizeof(char *));
printf("%d\n", sizeof(short *));
printf("%d\n", sizeof(int *));
printf("%d\n", sizeof(double *));
return 0;
}
这里我用的平台是32位的,所以指针变量的大小是四个字节,如果在64位平台下,指针变量的大小就是八个字节了。
十三. 结构体
我们生活中的事物是很复杂的,想要正确的描述他们,我们可能只靠数字和字符。比如描述学生,我们得说出他的名字、性别、年龄、班级等等。那么如何用C语言来描述呢?那就让我来介绍一下结构体吧!
结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。
举例,描述一个学生,包括姓名,学号,年龄,性别。
struct Stu
{
char name[20];//名字
int age; //年龄
char sex[5]; //性别
char id[15]; //学号
};
结构体的初始化:
struct Stu s = {"张三", 15, "男", "2021213158"};
接下来我们来试试使用结构体(两种方法):
//.为结构成员访问操作符
printf("name = %s age = %d sex = %s id = %s\n", s.name, s.age, s.sex, s.id);
//->操作符
struct Stu *ps = &s;
printf("name = %s age = %d sex = %s id = %s\n", ps->name, ps->age, ps->sex, ps-
>id);
程序输出结果:
总结
好啦,以上就是初识C语言的全部内容了。认真看完的话,我们应该就可以看懂别人写的代码了。最好呢是能够自己动手写一写代码。我给大家推荐几个刷题的网站吧:牛客网 | 力扣 | PTA
这是我的第一篇博客,肯定有很多不成熟的地方,希望大家多多评论提建议,感谢!
之后的博客应该会定期发布一些进阶知识和题目的讲解,希望大家到时候可以一起讨论,一起进步!