将来的你,一定会感谢现在拼命努力的你。
大家好,欢迎踏入C语言的世界,在这篇文章中,anduin会带你遍历C语言中的基本知识点,因为是初始C语言,我们对于知识点的讲解点到为止,只是对于C语言有一个初步的了解,方便我们以后将其一一剖析,当然我也会在一些地方做一些小补充,如果有不到位的地方,还请大家多多指正!(以下代码均在vs2022中编译)
目录
1. 什么是C语言?
计算机语言的发展
C语言和其他语言的区别
C语言编译器
2. 第一个C语言程序
主函数的标准格式
科普
返回值
printf
通用单位
数据类型
sizeof用法
计算方法
3. 变量与常量
3.1 定义变量的方法
3.2 变量的命名
3.3 变量的分类
局部变量与全局变量的定义
小思考
变量的使用
3.4 变量的作用域和生命周期
作用域
生命周期
理解
3.5 常量
字面常量
const 修饰的常变量
#define 定义的标识符常量
枚举常量
4. 字符串+转义字符
4.1 字符
字符的使用
ASCII码值小科普
4.2 字符串
字符串是什么
字符串的使用
隐藏的' \0 '
' \0 ' 的威力
小思考
4.3 转义字符
小测验
5. 注释
注释的作用
注释风格
6.选择语句
7.循环语句
8.函数
如何理解
函数的结构
实现Add函数
为什么使用函数
9. 数组
9.1 数组定义
9.2 数组的下标
9.3 数组的使用
结语
C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易 的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
低级 -> 高级
机器语言 ->助记符,汇编语言 -> B -> C
标准ANSI C 变换过程:ISO K&R C89/C90 C98 C99
C语言是一门面向过程的计算机编程语言,与 C++, Java等面向对象的编程语言有所不同。
常见的C语言编译器有Clang、Gcc、WIN - TC、SUBLIME、MSVC、Turbo C等。
#include
{
printf("hello world\n");
return 0;
}
//推荐
int main()
{
}
//古早写法
void main()
{
}
//不规范写法
main()
{
}
//不推荐但正确的写法
int main(void)//详细告诉你这个函数没有返回值
{
}
C语言中有一个约定,返回 0 表示正常返回,返回的是非 0,表示的是异常返回。
如果想在屏幕上打印数据,可以使用printf库函数,printf是一个C语言编译器提供的库函数。库函数使用要包含头文件.
计算机处理数据,处理的为二进制数据。
1 bit 存一个二进制位
1 byte = 8 bit 1 KB = 1024 byte 1 MB = 1024 KB 1 GB = 1024 MB TB ZB
为什么写代码?是为了用程序解决问题。
数据类型符号 |
数据类型 |
单位 |
char |
字符数据类型 |
1个字节 |
short |
短整型 |
2个字节 |
int |
整型 |
4个字节 |
long |
长整型 |
4个字节 |
long long |
更长的整型 |
8个字节 |
float |
单精度浮点数 |
4个字节 |
double |
双精度浮点数 |
8个字节 |
sizeof是操作符,sizeof计算单位的结果是:字节 - byte。
sizeof(long) >= sizeof(int),也就是说long长整形只要大于等于int整形就可以了,在vs2022中计算出long的大小为4个字节。
#include
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;
}
//编译结果:
// 1 2 4 4 8 4 8
生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等)
有些值是可变的(比如:年龄,体重,薪资)
不变的值,C语言中用常量的概念来表示,变的值在C语言中用变量表示。
int age = 150;
float weight = 45.5f//加f原因:编译器默认为double类型。如果想定义为float类型,就加上f
char ch = 'w';
1)只能由字母(包括大写和小写)、数字和下划线(_)组成。
2)不能以数字开头。
3)长度不能超过63个字符。
4)变量命中区分大小写的。
5)变量名不能使用关键字。
变量分为两种类型,一种为全局变量,一种为局部变量。
局部变量适用于局部范围内,全局变量适用于全局范围,在整个项目中都有效。
#include
int global = 10;//全局变量
int main()
{
int local = 1;//局部变量
return 0;
}
下列代码有没有问题,若没有问题输出的值是什么:
#include
int num1 = 2019;//全局变量
int main()
{
int num1 = 2020;//局部变量
printf("num1 = %d\n",num1);//打印结果是什么?
return 0;
}
在vs2022中编译结果如下:
因此我们可以得出:当局部变量和全局变量同名的时候,局部变量优先使用。
#include
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;
}
作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的而限定这个名字的可用性的代码范围就是这个名字的作用域。
1)局部变量的作用域是变量所在的局部范围。
2)全局变量的作用域是整个工程。
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段。
1)局部变量的生命周期是:进入作用域生命周期开始,出作用于生命周期结束。
2)全局变量的生命周期是:整个程序的生命周期。
对于作用域和生命周期,如果光看定义可能很难理解,接下来anduin就用一个例子来帮助我们更好地理解这个概念,生命周期可以看做从anduin从出生到死亡这个范围,但是作用域呢可以看成auduin可以坚持写代码的时间,当我的作用域结束之后,我的生命周期并没有结束。这两个是不同的两个概念。
就是直接写出的常量值如 30,3.14,"abcdef",'a'等等....
#include
int main()
{
const int num = 100;
num = 200;//报错
return 0;
}
当我们对num进行二次赋值是发生报错,这是因为 const 修饰的变量无法被重新写入。
那么常变量又是什么,我们怎么理解他呢?
num 本质是变量,但是因为 const 的修饰限定了他的改变, 就和常量一样。
如果想更加深入理解关键字 const 可以参考我的一篇博客http://t.csdn.cn/PtuDv
#include
#define MAX 1000
int main()
{
int a = MAX;
printf("%d\n", a);
//MAX = 2000;//报错
int arr[MAX];//可以
return 0;
}
当我们对MAX进行二次赋值时,发生报错,这可以看出MAX为常量。
但是#define 定义的标识符常量可以用来定义数组元素个数如int arr[MAX];
由于#define起替换作用,这里的数组相当于int arr[1000];
枚举从字面意思上看就是一一列举,生活中很多东西都可以一一列举,它们都可以用枚举来表示。
代码演示:
enum Sex
{
MALE,
FEMALE,
SECRET
};
int main()
{
enum Sex s = SECRET;
printf("%d %d %d\n", MALE, FEMALE, SECRET);//0 1 2
MALE = 3;//报错 证明
}
我们编译后发现在对枚举定义MALE进行赋值时报错,所以我们可以得出结论在枚举类型enum Sex中列举出的可能取值都是枚举常量。而枚举常量中首个元素被默认初始化为0,在进行打印时,打印结果为0 1 2。枚举常量中的状态值是呈+1式递增的。
Tips:枚举常量的初始状态值可以被改变,输出的枚举常量都是数字!!!
我们在键盘上敲出来的所有东西都可以理解为字符,字符一般用单引号' '来表示。
#include
int main()
{
char ch = 'a';
ch = 'x';
printf("%c", ch);
return 0;
}
字符的本质:ASCII码值
计算机中存储,表示都是二进制的,早期科学家们,为了区别字符,给每个字符都编了号,这个编码就称为ASCII码值。
Tips:常见的一些ASCII码值我们可以把它背下来,如0 - 48,a - 97, A - 65等等....
这种由双引号引起来的一串字符称为字符串字面值,或者简称字符串。("hello anduin.\n","a"," "这些都是字符串)。
注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。
#include
int main()
{
char arr[] = "abcd";
printf("%s\n",arr);
return 0;
}
#include
int main()
{
char arr1[] = "abcd";//此处可以结合内存来说明
char arr2[] = {'a', 'b', 'c', 'd'};
return 0;
}
接下来我们启动调试,查看arr1,arr2的内容。
在arr1的结尾处隐藏着一个'\0'作为结束字符串的标志,但是arr2中却没有' \0 '。
别看上述例子只是少了一个' \0 ',在这里' \0 '并不是摆设,它也是有自己的“威力”的。
在我们用代码看它的作用之前让我们先了解一下strlen函数。
strlen是一个库函数,在使用时需要引用头文件#include
函数作用:用来求字符串长度。
#include
#include
int main()
{
char arr1[] = "abcd";
char arr2[] = {'a','b','c','d'};
printf("%d\n",strlen(arr1));
printf("%d\n",strlen(arr2));//可以画图详细讲解
}
这里的输出结果是什么???让我们开始运行,我们看到结果如下:
我们不禁产生疑问,34是哪来的?原来这都是'\0'一手导致的。
分析:’\0'仅仅是字符串结束的标志,在统计长度时,并不会加上\0一起计算
故输出arr1的长度为4,由于arr2中没有\0,在求字符串由于\0并没有出现,所以便一直向后计算,直到遇到\0,这里面的长度也是包含了我们之前出现的烫烫烫的个数的!!!
所以'\0'的威力还是很大的。
如何输出这个路径?D:\Anduin_code\anduins-code-warehouse
这样可以吗?
int main()
{
printf("D:\Anduin_code\anduins-code-warehouse");
//输出结果:D:Anduin_codenduins-code-warehouse
}
但当我们运行之后,发现我们并不能输出我们的路径,这是为什么?因为这里\和其他字符构成转义字符。
转义字符,通俗点来讲就是在所有ASCII码前都可以用\加数字来表示,如\0,\t,\n等等,都可以被称作为转义字符。转义字符顾名思义就是转变意思。
下面我列出了一些转义字符:
转义字符 |
释义 |
\? |
在书写连续多个问号时使用,防止他们被解析成三字母词 |
\' |
用于表达字符常量 |
\" |
用于表示一个字符串内部的双引号 |
\\ |
用于表示一个反斜杠,防止他被解释为一个转义序列符 |
\a |
警告字符,蜂鸣 |
\b |
退格符 |
\f |
进纸符 |
\n |
换行 |
\r |
回车 |
\t |
水平制表符 |
\v |
垂直制表符 |
\ddd |
ddd表示1 - 3个八进制数字。如:\130x |
\xdd |
dd表示2个十六进制数字。如:\x30 0 |
让我们用代码了解他们都是什么作用(详情见注释):
int main()
{
printf("%s\n","(are you ok??)");//在老编译器上会打印(are you ok]
//三字母词:??) ->]
printf("%c\n",'\'');//输出结果为:'
printf("%c\n","\"");//输出结果为:"
printf("\a\a\a");//蜂鸣,电脑叫三声
char a[] = "abc";
printf("%c%c\b%c", a[0], a[1], a[2]);//输出结果为:ac(\b为退格符,b被删掉)
printf("1\t23");//输出结果为:1 23(\t是水平制表符,八个空格)
printf("anudin\n");//输出结果为:anduin且换行
printf("%c\n",'\130');//输出结果为:X (1*64+3*8+0*1 = 88 也就是字符 X)
printf("%c\n",'\x30');//输出结果为:0 (3*16+0*1 = 48 也就是字符 0)
}
看到这儿大家应该对转义字符有一定的理解了,接下来就用几道题目来测验一下自己吧:
题1:如何正确输出代码路径:D:\Anduin_code\anduins-code-warehouse?
题2:这个路径的长度是多少?
#include
int main()
{
printf("D:\\Anduin_code\\anduins-code-warehouse?");
printf("%d\n",strlen("D:\Anduin_code\anduins-code-warehouse"));
return 0;
}
1)代码中不需要的代码可以直接删除,也可以注释掉。
2)代码中代码比较难懂,可以加注释文字。
#include
int main()
{
//printf("hello anduin\n");C++注释风格 推荐
/* C语言风格注释 不推荐
printf("oops!\n");
*/
}
C语言注释风格由于\*总是和更近的*/进行匹配,从而导致无法嵌套注释,所以我们一般还是用C++风格的注释。
我们的生活处处都有选择,在C语言中也不例外,存在着选择语句。
举一个比较简单的例子:如果你坚持好好学习,那么以后可能会收获一份好offer。
但是如果你不好好学习,那你可能会被社会淘汰。
代码演示:
int main()
{
int studying = 0;
printf("你会坚持每天学习吗?(1 or 0):>");
scanf("%d",&studying);
if(studying == 1)
{
printf("好offer在等着你!\n");
}
else
{
printf("竹篮打水一场空!\n");
}
对于你,你会怎么选择呢?是选择1 好offer,还是选择 0 竹篮打水一场空呢?
anduin这里还是建议大家努力起来,一起加油!
当然分支语句可不仅仅是这么点,我们今天只是了解,等之后会我会重新整理的。
有些事必须一直做,比如我们日复一日的学习敲代码。
这也就形成了一种循环,C语言中有一种语句叫做循环语句,我们接下来就来了解一下它,循环语句分为三种:
- while语句
- for语句
- do...while语句
我们今天就重点看一下while语句,其他两种循环语句,我会在以后详细讲解:
while(表达式)
循环语句;
我们可以通过一个例子来了解一下while语句是如何进行的,比如你坚持写代码,当你代码写到两万行时,你可能觉得你的水平差不多了,也可以找个offer了,那么这个循环也就随之结束。如下面代码所示:
#include
int main()
{
int line = 0;
printf("insist codeing >\n");
while(line < 20000)
{
printf("写代码\n");
line++;
}
if(line == 20000)
{
printf("好offer\n");
}
return 0;
}
在我们学习数学的时候,也学过函数,它们表示为f(x),C语言中也存在着函数。
程序中存在main函数,那么除了main函数可不可以编写其他的函数呢?可以!!!
#include
int Add(int x,int y)
{
return (x + y);
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
scanf("%d%d",&num1,&num2);
sum = Add(num1,num2);
printf("%d\n",sum);
}
分析:用sum来接受Add函数所返回的值的同时调用Add函数,于是num1和num2在进行Add函数计算后,返回值为num1 + num2的值。
想象一下,如果这边有很多组数据要想加,使用平时的思路,我们需要初始化很多次,代码冗长,不美观,效率低,但是如果我们封装一个函数,可以达到事半功倍的效果。
如果要存储1-10的数字,怎么存储?
使用数组。
C语言中给了数组的定义:一组相同类型元素的集合
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};//定义一个整形数组
char ch[5] = { 0 };//对char类型数组不完全初始化,其中元素默认被初始化为0
char ch2[] = {'a','b','c'};//这样也正确
char ch3[] = { 0 };//正确,元素个数为1个,元素为\0
C语言规定:数组的每个元素都有一个下标,下标是从0开始的。
数组是通过下标来访问的。
代码演示:
#include
int main()
{
int arr[5] = { 1, 2, 3, 4, 5};
printf("%d\n",arr[3]);//访问下标为3的元素
//printf("%d\n",arr[10])//不可以这样访问!!!
}
请注意数组不能越界访问,例如:arr[10]就越界访问了!!!越界访问可能会导致程序崩溃,程序出错等严重后果。
设想一下:你在一层楼中买了两套房子,但是你自己的房子不住,偏偏要去住别人的房子,这是什么,这就是非法访问,严重的是要被抓起来了,就说明你违法了!!!所以越界访问的危险可见一斑。
#include
int main()
{
int arr[10] = { 0 };
//0~9
//输入10个值给数组
int i =0;
while(i<10)
{
scanf("%d",&arr[i]);
i++;
}
//输出数组的10个值
i = 0;
while(i<10)
{
printf("%d ",arr[i]);
i++;
}
return 0;
}
好了,初始C语言我们就先遍历到这,希望我的博客能对大家有帮助。如果大家觉得anduin写的还可以的话,请点赞+收藏哦!你们的肯定就是对我最大的鼓励!
今天也正好是端午节,祝大家端午安康,阖家欢乐!