初识c语言(三)


前言

亲爱的小伙伴们大家好啊!很开心我们又见面了,这篇文章是我们初始c语言的最后一篇文章了,马上我们就要进入c语言入门专栏了,毕竟这个初识c语言就跟名字一样真就是初识,目的是让初学者们能够大致的了解一下c语言的内容,正真想要更加全面学习的话,我们后面的c语言入门,和c语言进阶会有更加全面的讲解,并且啊作为一名负责的作者啊,我还特意又开了两个专栏就是有趣的c语言游戏,和c语言练习题这个会跟着我们c语言入门的更新而相继更新,目的就是为了能让我们小伙伴们能够巩固相关的知识,好啦我们废话不多说开始这篇文章的讲解。

一.操作符

c语言是一个非常灵活的语言,因为c语言提供了非常丰富的操作符,所以我们在使用的时候就十分的灵活,那我们来看看有哪些操作符,当然这里有些操作符涉及到二进制,那么这些操作符我们先不讲,我们以后会详细讲解。

1.算数操作符

我们首先看看有哪些算术操作符:+-*/%
第一个就是加,第二个是减,第三个是乘,我想这些大家应该再熟悉不过了,不能说是从出生就开始接触,那也应该是从出生2,3年后就开始接触,但是后面的算数操作符,我想还是有些许知识点需要给大家讲解一下的,我们先来看个例子在我们数学当中7÷2=3…1,这里的结果我们一般叫商3余1,那么我们这里的3就是操作符\得到的结果,这里的1就是我们的%得到的结果,那这里我们用数字是怎么来表示的呢?就是7/2=3 , 7%2=1也就是说我们这里的/操作符得到的结果应该是我们算数中的商,而我们的取模操作符(%)得到的结果应该是其余数,我们可以再来看几个例子:11/2=5 ;11%2=1 13/2=6;13%2=1等等等这样的例子很多大家可以下去尝试尝试。

算术操作符中需要注意的几个小点

第一点当/的两端都是整数的时候,执行的结果就是整数。但是当我们两端有一个为浮点数的时候我们的执行结果就是浮点型。那这里的/就跟我们上面说的作用不一样了,我们上面的/的两端都是整形的时候只能得到商,而我们两端只要有一个是浮点型的时候,我们得到的结果跟我们用脑子算的结果一样,就是可以有小数,这里我们可以看个图片来理解理解

#include<stdio.h>
int main()
{
	int a = 9;
	a = a / 2;
	printf("%d\n", a);
	float b = 9.0;
	b = b / 2;
	printf("%f\n", b);
	printf("%.1f\n", b);
	return 0;
}

请添加图片描述
我们先定义一个整形的变量,让其除以2可以看到我们得到的结果为4,而我们再定义一个浮点型的变量b,变量a,b的值相同除以相同的数,但是我们发现结果却不相同他的结果为4.5,而且类型也不相同类型为浮点型,这就是我这里要说的一点就是当/的两端都是整数的时候,执行的结果就是整数。当我们两端有一个为浮点数的时候我们的执行结果就是浮点型。这里我们发现后面的0很多,我们要想把这些0去掉的话,我们可以让其打印的时候只打印小数点后一位,可以在%f中的%后面加上.n这个n就是你想要打印小数点多少位。
第二点: 这时候就有小伙伴们脑洞大发了,我们取模操作符是不是也可以在两端加个浮点型啊!啊这里不行我们规定取模的两端必须是整数,我想这里应该很好理解。

2.移位操作符

这里应该详细的说是移(2进制)位操作符,<< 这个是左移,>> 这个是右移我们先来看个代码

#include<stdio.h>
int main()
{
	int a = 1;
	int b = a << 1;
	printf("%d", b);
	return 0;
}![请添加图片描述](https://img-blog.csdnimg.cn/16ac289a9f124b91978d5faeff281724.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-26LaF5Yeh,size_20,color_FFFFFF,t_70,g_se,x_16)

大家可以想想这个代码的运行结果是什么,这里我们的创建的一个变量a,其大小是四个字节,那么我们用二进制的形式来表示是不是就是00000…0001,然后我们这里的左移一位是什么意思呢?我们来看看我们这个图片请添加图片描述
这个向左移就是将这个整个数字向左移,然后这时候会多出来一个数字,同时也会产生一个空位,那么空位我们会填上0,多出来的我们就会去掉,我们看了这个图片应该能明白这个过程,那我们这里打印出来的值也自然是2,当然我们可以移多个位置不只是1,那么我们这里的右移的也是一样的由于是我们这里是初识c语言我们这里就不进行过多的介绍,大家了解就好。

3.位操作符

&这个叫按位与,|这个叫按位或,^这个叫按位异或。我们来举一个例子大家就明白了什么意思啦,我们创建一个变量 a等于3,然后再创建一个变量让其等于5,那么我们用二进制表示出来3就是000…011,5就是000…110那这里我们进行简化3就直接写成011,5就是直接写成110我们把这个竖着写
请添加图片描述
按位与就是只要这竖着的两个数中有一个是0,那么这竖着的两个数的结果就是0,只有两个都是1 的时候才为1,那么我们这里a&b得到的结果就是001,安位或就是只要有一个为1,那么结果就为1,那么我们这里的结果就是a|b的结果就是111,按位异或的规则就是对应的二进制位相同则为0,对应的二进制位相异则为1,那么我们这里的a^b结果就是101,看到这里我们应该能对其有一定的了解我们后面会跟大家进行更加详细的讲解。

4.赋值操作符

我们的赋值操作符有:

请添加图片描述
那我们接下来来一个一个介绍

1.=

这个操作符大家应该见的地方应该很多,但是有两点大家要注意一下。
第一点:

int main()
{
	int a = 0;//初始化
	a = 10;//赋值
}

我们第一个的=叫做初始化,我们第二个=才叫做赋值。
第二点:
我们在判断相等的时候用的不是=而是==,因为数学从小到大都是一个等于号,所以在这里很多小伙伴们在敲代码的时候,就会不知不觉的写成一个=而造成了死循环。比如说

int main()
{
	int a = 0;
	scanf("%d", &a);
	while (a = 10)
	{
		printf("hello world\n");
	}
	return 0;
}

这里不管我们输入什么数字,我们都会打印hello world,并且还会不停的打印进入一个死循环的状态,这就是因为我们把==写成了=所以这里的判断语句就不是判断这里的值是不是等于10,而是这个判断式里面装了一个表达式这个表达式的结果就是a=10,所以这里判断式的结果就是10,10是非0也就是真,所以这里会不断的执行下面的循环语句。
请添加图片描述

2.+=

这个也十分的好理解,我们在写代码的时候会出现这种情况a=a+3;这个意思就是让a的值加上3,那么我们就可以将其简化直接写成a+=3;啊这个属实没啥好讲的,没啥理解成本嘛,大家唯一要记得就是别写反了就行。

3. -=
我们在写代码的时候会出现这种情况a=a-3;这个意思就是让a的值减去3,那么我们就可以将其简化直接写成a-=3。可以类推哈。

4.*=
我们在写代码的时候会出现这种情况a=a3;这个意思就是让a的值乘以3,那么我们就可以将其简化直接写成a=3。可以类推哈。

5. /=
这个也可以类比上面的,而且这个/跟我们上面说的那个一样当两端只要有一个浮点型那么算出来的结果就是浮点型,但是大家这里要注意的是,如果你除以的数是浮点型的话,那你创建变量的话也得是要浮点型的不能是整形的,如果是整形的话,可能会照成数据丢失的情况。
6.
&=
|=
>>=
<<=
^=
这些操作符大家可以类比上面这里就不过多的进行介绍了因为都差不多。

5.单目操作符

我们先来聊聊什么叫双目操作符,比如说a+b这个+就是一个双目操作符,因为这一个操作符对应着两个操作数,所以我们将其称为双目操作符。那么我们单目操作符呢?是不是可以进行类推那是不是就是一个操作符对应着一个操作数。好我们现在理解了什么是单目操作符那我们来看看有哪些单目操作符请添加图片描述
.1. !

我们先来看个例子:
请添加图片描述
这里我们用if语句进行判断,我们这里如果为真就打印hello world,如果为假就打印byebye,我们这里令a=10,并且直接将a放到括号里面进行判断,因为非0就是真,所以毫无疑问我们这里会打印hello world。那我们这里要是在判断的部分加上一个!操作符会发生什么样的变化呢?我们再来看一张图片请添加图片描述
这里我们加了一个!操作符后就打印了byebye,那这里是怎么回事呢?我们想想,我们这里之所以会打印byebye是不是因为第一个if那里判断的结果为假,但是我的a是=10的啊!为什么会为假呢?那么这里就得说我们的!逻辑反操作符的作用了,这个我们根据名字也可以得知就是将真的变成假的,将假的变成真的,那我们回来看这个例子a=10,本来判断的结果应该为真,但是我们前面加了一个!所以这里的真变成了假,所以就会打印byebye。

.2. -

这个也是个操作符其作用就是跟我们数学中的一模一样,可以在正数前面加个-使其变成负数,也可以在负数前面加个-,将其变成正数我们可以看个代码了解一下

int main()
{
	int a = 0;
	a = 10;
	a = -a;
	printf("%d\n", a);
	a = -a;
	printf("%d\n", a);
	return 0;
}

这里毫无疑问打印的结果第一个为-10第二个的结果为10,所以这里的-负值操作符的作用和我们数学中的作用一模一样哈,但是这里大家要注意一下哈,我们这里是单目操作符,不是双目操作符不要把这里的看成了a-b的这个操作符了哈。

.3. +

啊哈有些同学看到上面的负值操作符,现在看到了这个正值操作符可能会感觉到啊这个是不是可以在负数前面加个+使得负数变成正数啊。答案是不行哈请添加图片描述
我们可以看看这个运行的结果很明显发现不行,那有同学就会问了那这个操作符有啥用啊,我只能很不好意思的说,确实没啥用。哈哈哈哈哈哈真的没骗你。当然哈不要把这个当成双目操作符的+了哈。

.4.&

这个叫取地址操作符,这时候小伙伴们就要问了,啥叫取地址操作符,那能得到我的外卖地址码?当然不是。我们在创建变量的时候,会向电脑申请一个空间,这个空间将会存储数据,而每个空间都会有一个对应的地址,那我们就可以用这个取地址操作符得到这个申请的空间所对应的地址,我们来看下面这段代码。
请添加图片描述
我们这里的%p是用来专门打印地址的,而我们用&取地址操作符来取出a的地址并且将其打印出来,所以通过这里我们可以很好的了解&取地址操作符的作用,当然这时有小伙伴们可能还是不大了解,不要慌我们后面就会讲到指针,看完那部分的内容,你肯定能了解到这个操作符的作用。

.5. sizeof

这个操作符想必大家在前面的文章已经见过几回了,他的作用就是以字节形式给出了其操作数的存储大小。 操作数可以是一个表达式或着括在括号内的类型名。比如说我们前面讲的printf("%d",sizeof(int))这个sizeof的作用就是得出int这个类型所占的空间的大小,当然这里不仅仅可以求出不同的类型的大小我们,我们还可以创建一个变量,然后用sizeof求出这个变量所占的内存大小,我们可以看一下这个张图片
请添加图片描述
当然这里我们说sizeof它是一个单目操作符,而不是一个函数那我们是如何来证明这一点的呢?因为函数的后面必须得有一个括号来传参数,那么如果我们的sizeof的后面可以不加括号的话,那是不是就可以验证它不是函数呢?那么我们这里可以看到,当我们的要求的是变量的大小的话,我们的sizeof的后面是可以不加括号的,但是当我们要求类型的储存大小的话,那还是得加括号。当然我自己本人觉得这个括号还是都加为好统一一点嘛。其实讲到这里基本上该操作符的内容就差不多该说完了,但是还有一点需要高数大家的就是我们在用sizeof求数组大小的时候,同学要看清楚一点不要弄混了比如我们下面的两个代码

int main()
{
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	printf("%d", sizeof(arr));
	printf("%d", sizeof(arr[0]));
	return 0;
}

我们可以看到这两个printf打印出来的值,我们的第一个sizeof(arr)这个求的是整个数组所占的内存的大小,而我们后面的sizeof(arr[0])这个求的是数组中的一个元素的所占的内存的大小,大家不要搞混了哈,那么这里我们其实可以得到一个东西,就是以后我们在求整个数组的元素的个数的时候我们可以采用这样的方法int num_arr = sizeof(arr)/sizeof(arr[0]); 。好啦这个sizeof操作符我们就先讲到这,想必大家应该能够理解明白。
.6.~
这个操作符的作用是按(2进制)位取反,那这个我们怎么来理解呢?比如说1010这个段二进制的数按位取反那就是0101就是把0改成1改成0,那这里我们就可以看一个例子:

#include<stdio.h>
int main()
{
	int a = 0;
	int b = ~a;
	printf("%d", b);
	return 0;
}

这里我们创建了一个int类型的变量将其初始化为0,那么我们一个int类型的大小是不是4个字节,那我们将0的二进制形式写出来的话那是不是就是32个0
00000000000000000000000000000000,那我们这里再创建一个变量b,然后将a按位取反赋值给了b,那我们这里将b打印出来会是多少呢?啊这时候就有小伙伴就要说了这还不简单嘛,不就32个1组成的二进制的数字嘛,那我们这里的结果是这样的吗?我们可以运行一下发现结果为-1,可能与一些小伙伴们想的不一样,那这里我们就得讲讲源码,反码,补码。我们的负数在内存中的存储的时候,存储的是二进制的补码,而我们在打印的时候打印的这个数是源码,我们之前讲过这个最高位是用来表示正负的,那我们这32个1是不是也就表示的是负数了,那我们这打印出来的数字是不是也就不是我们这里的32个1,因为这32个1是补码,而我们打印需要的是源码,那我们这里就再得说说源码,反码,补码之间的关系:源码的符号位不变其他位按位取反得到反码,反码加1得到补码,那反过来是不是就是补码减一得到反码,反码除了符号位得到源码,那我们这里的补码就是32个1,那么补码减一得到反码也就是11111111111111111111111111111110,那我们的源码就是除了最高位其他都按位取反也就是10000000000000000000000000000001那我们打印这个二进制的数是不是也就是-1了,看到这里想必大家对这个操作符应该能够理解清楚
.7. ++ - -
其实这两个操作符我们在循环里面见到的比较多,比如说a++这个在循环里面见到的次数太多了,这个意思就是每次执行完a++之后,我们a的值都会加上1,那么- -就很好理解,那不就是a的值减去1嘛。虽然这个确实很简单,但是我们这里还是有一点需要大家注意的,就是我们这里分为前置++和后置++,我们来举个例子:

int main()
{
	int a = 10;
	int b = 0;
	int c = 0;
	c = a++;
	printf("%d", a);
	printf("%d", c);
	b = ++a;
    ![请添加图片描述](https://img-blog.csdnimg.cn/007270764ba84c2594aa5bcb7e1f1ce0.png)
printf("%d", a);
	printf("%d", b);
	return 0;
}

这里我们创建了三个变量,我们一开始将a的值初始化为10,然后再创建两个变量b c,这里我们是让c=a++;那么我们再看这里是后置++,我们的后置++的规则是:先等于再加加,那我们这个怎么理解?我们就看这个例子:a的值一开始为10,我们让c=a++,那我们我就应该先让c等于a的值,再来a=a+1,也就是说我们这里的c是等于10,然后我的a的值再加上1,a就等于11。好看完了这个我们再来看我们下面的b=++a,这里的为前置++,那我们前置++的规则是:先加加再等于。那我们这里的a经过上面的计算a的值变为11,所以我们这里的b=++a,也就是先让a的值加上1等于12,再让b等于a的值,那么我们这里的b就等于12。我来看这个代码的运算结果:
请添加图片描述
结果跟我们说所的一模一样,看到这里想必大家对前置++和后置++应该能够了解的十分的清楚。当然哥们写的这部分内容的时候突发奇想,这个++的意思好像跟我们前面讲的+=有点像啊!对吧那我这里的++能不能改成+=1呢?可以是可以但是这里就没有前置后置的区别,这里好像只有放到后面,如果你放到前面的话,编译器会报错。请添加图片描述

并且运算的顺序也是先把后面的表达式运算完再来赋值。我们可以看张图片便可以得知。
请添加图片描述
.8.*
啊这个操作符我们这里就不多做讲解因为这个操作符我们会在本片文章的指针的这一块做出详细的讲解。

.9.( )
这里我们叫他强制类型转换的操作符,听到强制类型转换,想必大家应该能猜到这个操作符的意思,我们这里创建一个浮点型的变量float a= 3.14; 我们这里创建了一个浮点型的变量a,这里看上去没有错,但是我们要知道的是,我们的编译器在看到字面浮点数的时候,会默认理解为double类型,所以我们在创建float类型的变量在初始化的时候我们要在小数的后面加上一个f所以就应该为float a = 3,14f; 才能保证我们创建的变量为float类型。请添加图片描述
好那我们来回头看这个强制类型转换这个操作符,比如说我们上面的b是浮点型,那我们可以用()将他强制性的转化为整形,并且赋值给一个整形的变量,我们可以看看下面这张图片请添加图片描述
大家可以多去尝试尝试不同的内省的转换,不是只有浮点型装换为整形。看到这里对()这个操作符应该有所了解,但是大家还是要注意的一点就是:括号里面装的是你想要转换的类型而不是内容哈。

6.关系操作符

我们先来看看有哪些关系操作符
请添加图片描述
说实话这个内容我是真的不知道该怎么讲了,因为这再熟悉不过了吧这不就是数学中用来判断的大于,大于等于,小于,小于等于嘛,但是最下面的那两个还是得说一下:5.!=表示的是不等于的意思,我之前讲过的!表示的是逻辑反,那么这里的!=不就很好理解嘛,正的意思是等于,那么反的意思不就是不等于了嘛。好6.== 这个是等于的意思,常用于判断是否相等。这里要记住用于判断相等的操作符是==不是=,大家在敲代码的时候别搞混了。

7.逻辑操作符

我们的逻辑操作符就只有两个:
请添加图片描述
其实这个很好理解,第一个&&可以理解为汉语中的并且的意思,第二个||可以理解为汉语中或者的意思,我们更详细的来看(表达式1)&&(表达式2)只有&&两端的表达式1和2都为真的时候,整个表达式才会为真,只要有一边的表达式为假那么这整个的表达式就为假。(表达式1)||(表达式2)两端的表达式只要有一边的表达式判断为真,那么整个表达式就为真,当然两端都为假时才判断为假。我们来举一个例子我们输入一个数字如果他大于3小于10的话就打印hello world否则我就打印bye bye。那这时候可能就会小伙伴就说啦,啊这还不简单吗,我高中天天做分段函数

int main()
{
	int a = 0;
	scanf("%d", &a);
	if (3 < a < 10)
	{
		printf("hello world\n");
	}
	else
	{
		printf("bye bye \n");
	}
	return 0;
}

这时有小伙伴就要尝试了,你可能输入了一个5,你会发现成功的打印了hello world,于是你再输入一个8你发现你也打印了hello world,当你以为这个代码正确的时候你又输入了一个11,结果你发现他也会打印出来hello world,然后你就会感觉的十分的奇怪,于是你再试着输入了一个1结果他还是打印hello world。那为什么会是这样的呢?其实这里的问题就出在了我们括号里面的判断语句,3<a<10编译器其实是按两步走的,他会先拿a与3相比,如果a大于3那么就会返回1,如果a小于3那么就会返回0,而这个返回值就会再拿去跟10作比较,因为不管你返回的是1还是0你都比10小,所以这个表达式的结果永远为真,所以你不管输入什么数这个表达式的判断结果都为真。那我们这里怎么来写呢?这就得用到我们刚刚说的&&操作符,因为3<a<10这里可以看成a大于3,并且a小于10。所以我们可以改一下

int main()
{
	int a = 0;
	scanf_s("%d", &a);
	if ( 3 < a && a < 10 )
	{
		printf("hello world\n");
	}
	else
	{
		printf("bye bye \n");
	}
	return 0;
}

这样我们的这段代码就能够正常的运行,当然大家还可以试一试||这里我就不举例子了。

8.条件操作符

我们先来看看条件操作符长什么样哈。

exp1? exp2 :exp3

这就是我们条件操作符,他的意思就是如果表达式1的运算结果为真,那我们我这整个表达式的运行结果就是表达式2,如果表达式1的运行结果为假,那么整个表达式的运算结果为表达式3。我们也可以叫这个条件操作符为三目操作符。当然这么说大家也不是很能了解,我们来看个例子: 比如说我们要得到两个数字中的最大的那一个,那我们是不是可以用这个条件操作符

int main()
{
	int a = 3;
	int b = 10;
	int c = a > b ? a : b;
	printf("%d", c);

	return 0;
}

这里我们就可以用这个条件操作符求出两个数中的最大的那个,当然这里的条件操作符是可以做到嵌套的,比如说我的表达式2就可以又是一个条件操作符。那我们这里就不举例子了,大家可以自己下去尝试尝试。

9.逗号表达式

我们先来看看这个表达式长什么样哈。

exp1,exp2,exp3,exp4,.........expn

这就是我们的逗号表达式,逗号表达式的特点是:从左往右依次计算,整个表达式的结果是最后一个表达式的结果。那我们这里怎么来理解呢?例如:

int main()
{
	int a = 10;
	int b = 11;
	int c = 12;
	int d = (a = a + c, b = a + b, c = b + c, a + b + c);
	printf("%d", d);
	return 0;
}

我们这里创建了三个变量分别为a,b,c然后我们看下面的逗号表达式,根据我们逗号表达式的语法规则我们是从左往右依次开始依次计算,我们首先看第一个a=a+c这里我们的a一开始是等于10,c等于12所以我们这个表达式计算完后得到的结果为a=22,我们再来看第二表达式b=a+b,因为一开始我们的b等于11,而在经历了表达式1后我们的a已经变成了22,所以我们的表达式二的运算结果应该为b=22+11=33,我们再来看表达式3,c=b+c这里的b在经历了表达式2后b的值变成了33,c的值一开始为12所以我们这里的c就等于33+12=45,因为a+b+c是最后一个表达式,所以我们这里的d的值就是我们这个逗号表达式中的最后一个表达式:a+b+c,那我们再根据前面的表达式的运算的结果可以得知这里的a=22,b=33,c=45,所以我们这里的d也就等于了100.

10.下标引用,函数调用和结构体

.1.下标引用
我们先来看看下标引用这个操作符长这个样[ ]啊这个大家是不是非常的熟悉啊,这个[ ]经常的出现在我们的数组当中,我们首先创建了一个数组
int arr[ 10]={1,2,3,4,5,6,7,8,9,10}; 那这时我想修改数组中第三个数据的时候我该怎么办呢?那这时这里的下标引用操作符的作用就出来了,我们可以arr[2]=11这样就可以调出第三个数据并且改变数据的内容,这里的[ ]就是下标引用操作符,而arr和2就是操作数,那么这个操作符的作用就是调出数组arr中的第3个数据。这里有一点是大家要注意的就是:我们在创建数组的时候[ ]里面是不能使用变量的,但是我们在调用数组的时候却可以使用变量,这是因为我们在创建变量的时候需要一个确定的值来申请空间,不能是一个变量,所以我们在创建数组的时候[ ]里面得是一个确定的常数,不能是变量。而我们在引用数组里面的数据的时候,因为该数组的内存大小已经确定了,无需再申请空间了,所以我们在引用的时候就可以使用变量。

2. 函数的调用
我们先看个图片这里我们创建了函数,该函数的作用就是得出两个数的和。

int add(int x, int y)
{
	return x + y;
}
int main()
{
	int a = 10;
	int b = 11;
	int sum = add(a, b);
	printf("%d", sum);
	return 0;
}

这里我们可以看到我们创建了一个函数add而我们函数的后面的()就是我们的函数调用操作符,也就是说在使用函数的时候都会用到函数调用操作符,那我们这个操作符的操作数就是:add ,a,b。当然其实我们说到这里我们可以返回来看我们之前讲的操作符sizeof我们说当他的后面是一个变量的时候我们是可以不要括号的,那么这里是不是就反过来说明了我们的sizeof不是函数而是操作符对吧,因为可以不加括号嘛。

.3.结构体
这里的内容我们放到本文章的最后进行讲解。

二.常见的关键字

关键字是c语言本身内置的,关键字不是自己创建出来的,也不能自己创建所以我们在自己创建变量的时候有这么几个准则就是:
1.变量的名字不能是关键字。
2.名字必须是字母,数字下划线组成,不能有特殊字符,同时不能以数字开头。
3.还得有意义。

那我们接下来就看看有哪些关键字:
请添加图片描述
这里我们可以给这些关键字分分类,然后我们再讲解一些关键字的作用。

  1. 我们将for ;while;do while ;break ;continue 这几个关键字放到一起是因为这些关键字都是关于循环的,比如说for循环,while循环和do while循环,这里的break和continue就是用来修饰这里的循环的,具体的功能我们下一章循环专门来讲。
  2. 我们将switch ;case;default放到一起因为这些一起构成了switch语句,当然switch语句中也有break,但是break在上面就放一起了,所以我们这里就没有将break和他们放一块。
  3. 我们将if ;else放到一块因为这些可以构成if的选着语句。
  4. 我们将char ;short;int; long; long long;float ; double ;signed;unsigned; 放到一块,因为这是我们之前讲到的变量的类型,后面的signed和unsigned就是修饰的变量是否有符号,也就是是否有负号。
  5. 我们将enum;struct ; union放到一块enum我们之间见过这是枚举,struct是结构体,union是联合体(共用体)
  6. 剩下的我们就不大好分类了,我们就单一的讲讲。extern这个我们在讲全局变量的时候讲过是用来声明外部的符号,他可以用于使用其他文件所定义的全局变量,和函数。return这个可以经常在函数中出现用于返回某些值。void这个我们也经常在函数中见到。void经常用于函数,常表示该函数无返回类型,也可以表示函数无参数。goto这个常常用来实现跳转在下一篇文章大家就可以看的到。const常常用来修饰变量使得变量变成常变量,这个我们之前讲过。好接下来有几个关键字就需要我们来好好讲讲。

typedef

我们来介绍一些这个关键字的作用:typedef顾名思义是类型定义,这里的应该理解为类型的重命名,那这是什么意思呢?就是可以将名字复杂的变量进行简化,就好比在看的大家应该在小时候都有个小名,这个小名往往是大名改一下得来的,这些小名有几个特点就是:好记,好听,简单。那我们这里的typedef也是同样的道理,有些类型的变量名字太长了所以我们就可以有typedef来给他换个名字好写一点我们来举个例子:

typedef unsigned int uint;
int main()
{
	unsigned int num1 = 0;
	uint num2 = 0;
	return 0;
}

比如说我们这里创建了一个无符号的整形变量num1,但是我们这里觉得这个unsigned int这个类型的名字太长了,我们就可以使用typedef来给他换个名字我们就可以换成uint,那么接下来在创建变量的时候我们的类型就可以直接换成uint其意思跟unsigened int的意思一模一样。想必大家看到这个对typedef有了一定的了解,这个我们后面会跟大家进行详细的讲解。

static

这个static是用来修饰变量和函数的,那么这里我们就将其分为三种情况进行讲解:1.修饰局部变量-称为静态局部变量 2-修饰全局变量-称为静态全局变量
3.修饰函数-称为静态函数。那我们先来看看第一个。

1.static修饰局部变量

在了解static修饰局部之前我们先来看个例子:

void test()
{
	int a = 0;
	a++;
	printf("%d\n", i);
}
int main()
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		test();
	}
	return 0;
}

我们看一下这段代码的运算结果,我们发现这打印出来的全部是1,这里的原因也很简单,这里我们来看循环体里面就只有一个函数的调用,而我们的函数里面的内容是创建一个整形的变量a,然后a++再打印,等我们这个函数执行完之后我们的变量a的生命周期也就结束了,所以这个变量a也就会被注销的,他的内容也不会再保留,所以等我们循环再执行一次之后,我们会干着同样的事情创建变量a,然后再销毁变量,这样导致了变量a的内容不会被保存下来用于下一次循环,那么我们这里在变量a的前面加上一个static会出现什么样的情况呢?我们来看看下一张图片请添加图片描述
我们发现这里的结果就跟我们上一段的代码的运行结果不一样了,上一段代码打印的10个数字 全部是1,而我们这就变成了1到10,那这是什么原因呢?我们这里就有了两个猜测,第一:我们的每次循环加的数不一样,我们第一次循环a加的是1,然后第二次循环我们a就变成了加2,第三次循环之后a变成了加3依次往后推,如果是这样的话,那我们得到的结果确实是1到10。第二种情况:我们这里的a每执行完一次之后,其实他所占的内存并没注销掉,他的内容依然保留,这样的话得到的结果依然是1到10。那么我们现在来看这两种情况其实不难发现第一种情况就是我在瞎扯,那么我们这里的第二种情况就是我想要的,所以我们这里就可以得出一个结论就是:static修饰局部变量的时候,局部变量出了作用域不会销毁,本质上static修饰局部变量的时候改变了变量储存的位置,将栈区换到了静态区,影响了变量的生命周期。那这个栈区怎么来理解呢?我们电脑的内存可以大致的分为三个区间其分别为栈区,堆区,静态区,其中栈区是用来存储局部变量其特点为进入作用域创建,出了作用域就销毁。静态区则是用来存储静态变量也就是我们所说的全局变量而在这个区的变量的特点就是出了作用域不会销毁其生命周期跟程序的生命周期一模一样,那么了解了这些我们也就不难明白我们这里为什么能够打印出1到10,但是有小伙伴们这时候就要问了,那么这个程序中的变量a是怎么创建的呢?那我每次执行这个static int a=0;的时候又是怎么回事呢?他会不会因为我这个循环而每次都不停的创建空间呢?毕竟我这里是一个初始化的代码,那我们来看看这里怎么理解。好这里我们先按CTRL+Fn+F10开启逐过程,然后再用鼠标锁定代买static int a =0;再右键点击反汇编这样我们的界面就会成这样请添加图片描述
这里我们发现了一件奇怪的事情就是我们的static int a =0;这段代码他是没有对应的汇编语言的,那这也就说明了我们程序在执行的时候,我们的这段代码是不参与执行的,那也就说明了变量a所占的空间是程序在编译的时候就已经分配给他们,在程序执行的过程中是不会执行这段代码的,也就不会再创建空间。看到这里想必大家对static修饰局部变量已经有所了解。

2.static修饰全局变量

全局变量的概念和性质大家应该能够明白,因为我们之前聊过,那我们这里就来看看static修饰的全局变量会有什么不一样的地方,我们首先创建两个文件,在一个文件里面创建一个全局变量a,然后在另一个文件里面使用这个全局变量,并将a的值打印出来我们发现因为我们创建的是全局变量所以我们这里可以很轻松的实现请添加图片描述
于是我们就在这个全局变量前面加上static然后再运行一下,我们来看看结果请添加图片描述
啊这时候我们就突然的发现运行不了了,出现问题了,那这是为什么呢?当然这里的问题肯定是出在static身上,那我们这里就要讲讲:一段可执行的程序他是由编译+链接组成的,而我们的全局变量是具有外部链接属性的,所以一个全局变量可以在不同的文件中执行,这种功能是通过外部链接属性得到的,但是我们的static修饰全局变量的时候,这个全局变量的外部链接属性就变成了内部链接属性,所以我们其他的源文件就不能使用这个全局变量,但是本文件还是可以使用的,这也是我们上面为什么报错的原因。当然我们这里还是有小伙伴们会说了,啊这不就很鸡肋吗?功能越广不应该更好吗?其实不是这样的,你想想你的作用范围那么广,所有的文件都可以使用这个全局变量,所以每个人都可以改变这个全局变量,那以后我们这个地方是不是会变得更加的容易出错啊,对吧!跟我们做人一样的,事情不能管的太多了,不然会出事。

3.static修饰函数

其实我们的static修饰函数的情况和我们修饰全局变量的情况一模一样,我们的函数也具有外部链接属性,所以在static修饰后我们的外部链接属性就变成了内部链接属性,这也会照成其他的源文件无法使用。我们来看下面的例子就可以知道我们在一个文件里面创建一个add函数,其功能是得出两个数字的相加的值请添加图片描述
我们发现运行没有任何问题,但是我们在函数的前面加上一个static就会发现跟定义全局变量出现了一模一样的问题,同样是因为static改变了函数的链接使得函数的外部链接变成了内部链接请添加图片描述
想必看到这里大家对static函数有了一定的了解。

三.#define定义常量和宏

我们之前讲过#define定义的常量,那么我们这里再讲一个#define定义宏,这里我们就是初步的了解,具体的内容我们后期会详细讲解。我们来看一个例子,之前我们用函数的形式创建了一个add函数,用来计算两个数的和,那么这里我们换一个方法用宏的形式再来实现同样的功能。

#define add(x,y) ((x)+(y))
int main()
{
	int a = 10;
	int b = 11;
	int c = add(a, b);
	printf("%d", c);
	return 0;
}

这就是我们#define 定义宏的一个例子其中add我们这里称之为宏名,(x,y)我们称之为宏参数他是没有类型的,然后后面的((x),(y))我们称之为宏体,那我们这里的宏实行过程是怎么样的呢?我们下面出现了add(a,b),我们宏之间的传参是一一对应的关系,那么我们这add里面的a就会传给我们宏参数中的x,我们的b就会传给我们宏参数中的y,等传值完后我们的add(a,b)就会被((x)+(y))替换掉,所以我们这里的int c =add(a,b);就等于int c =((a)+(b));所以我们这里的宏就相当于一个替换的过程。我们这里就先了解一下,具体的内容我们后面会进行更加详细的讲解,因为是初始c语言嘛,我们就以了解为先。

四.指针

1.为什么会有指针

我们先来讲个故事,有一天你在宿舍里面十分的饿,然后食堂的菜你又不想吃,于是你就点了一个外卖,但是等了好久外卖小哥都没有送过来,这时你十分的生气,并且打电话给外卖小哥问为什么没有送到啊! 啊这时外卖小哥就说到:我已经到你楼底下了,你人在哪里啊?你就回复到,我在宿舍啊你送到宿舍来就可以了,然后外卖小哥就问道:你在哪个宿舍啊?你说:不知道啊?我们这里没有房号,你跟着定位来找我吧,啊这时你就发给外卖小哥一个地图说我就在星号的这个位置请添加图片描述
啊这时,外卖小哥头皮麻了一半,你这又没有一楼二楼的标识,又没有哪边是左哪边是右的标识,你这地图给了和没给差不多啊,那我们这个时候想如果我们这个宿舍楼有房号的话,那是不是会好很多啊,比如说我在A114这个宿舍,那是不是就是A 号楼 ,第一层楼第14 号宿舍,那是不是就变得好找了很多对不对,那我们的电脑的内存也是如此内存是电脑上特别重要的储存器,计算机中的程序的运行都是在内存中进行的。所以为了有效的使用内存,就把内存划分为一个个小的内存单元,为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号就被称为该内存单元的地址。那这跟指针有什么关系呢?因为每个内存单元都有对应的编号,我们就把这个编号称为地址,而我们又把这个地址称为指针。

2.指针的是如何产生的,以及内存的大小的计算

那我们这里的指针是如何产生的呢?换句话来说,我们的地址又是如何产生的呢?我们以前买的电脑的内存一般都是4g的那这是为什么呢?带着这些疑问我们来进入这一小点,因为我们就拿32位的电脑举个例子,32位的电脑里面也就存在着32根地址线,而这些地址线通电就会产生电脉冲,那么通电就是1,没电就是0,那么一共有多少种情况呢?那是不是就是00000…00000(一共32个)到11111…111111(一共32个)这么多个地址,那是不是就是一共有2的32次方个地址编号,那我们再来看这些地址编号可以用来标记一个内存单元,那我们的内存单元的大小又是多少呢?我们先假设一个内存单元的大小是1bit,那我们来看这个内存的大小是多少:2的32次方等于4294967296,那内存也就是4294967296bit=536870912byte=524288kb=512mb=0.5gb那我们看这个假设是不是太小了,那我们再来看,如果一个内存单元是一个字节的话,那我们以此内推的话是不是也就是4gb,那我们这么看的话,我们就发现这个大小就十分的合理。所以我们的一个内存单元的大小就是一个字节。好看到这里想必大家已经有了初步的了解,但是这里出现了一个问题就是我们这里的数字太多了啊我们不可能每次写地址的时候都写32个数字吧,所以这里的地址我们就采用16进制的写法我们的10进制是0,1,2,3,4,5,6,7,8,9所以我们的16进制的是0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g这里的a就代表了10后面就依次类推。所以4个2进制的数字就代表了1个16进制的数字所以我们32个2进制的数字是不是就可以用8个16进制的数字进行代替,那我们的地址的编号的书写是不是就方便了很多比如说0x00000001这就用看起来方便了多,要是用2进制那是不是就很难看啊这里就不演示了大家 注意了这里的0x表示的是16进制.

3.如何储存地址

我们前面说为什么会有指针,以及指针的意义和一个内存单元所表示的内存大小,那我们这里看看如何把地址提出来,以及地址如何储存地址。这里我们就先来介绍一下一个操作符&,这个可以将变量的地址提出来,比如说我们创建了一个变量a,那么这个变量a就会申请一个空间,那这个空间是不是就会对应一个地址,那么这个&就会把这个a申请的空间对应的地址得出来,我们来看个例子就知道了

#include<stdio.h>
int main()
{
	int a = 1;
	int *p = &a;
	printf("%d", a);
	return 0;
}

这里我们创建了一个变量将其初始化,于是我们想要得到这个a的地址,那么是不是得用到&这个操作符,但是我们取出来了我们得用变量来储存这个地址啊,那么这里我们可以看到我们创建了一个指针变量p来存储这个地址,我们变量在初始化的时候前面都会有对应的类型,但是这里就有小伙伴们发现了这个p的前面的int*是什么意思啊,那么这里我们来说一下这个int代表的意思就是我们这个地址所对应的值是个整形,也就是这个变量a对应的内容是整形,因为这个地址对应的就是a嘛,我们这里的*代表的意思就是我们这个指针变量p里面的内容是地址。所以看到这里我想小伙伴应该能够明白一点这里我们再来试试如果我们这里的变量a的类型是字符型呢?那我们的是不是只用把int * 改成char*是不是就可以了啊,对吧这个char表示的这个地址对应的值的类型是char,这个*表示的是这个变量a里面装的内容是地址。看到这里想必大家因该能够明白如何存储地址了,那么这里如何将地址打印出来呢?这里我们可以使用printf函数这里的%p表示的是打印的类型为地址类型

#include<stdio.h>
int main()
{
	int a = 1;
	int *p = &a;
	printf("%p\n", p);
		return 0;
}

我们看看这个代码的运行结果为
请添加图片描述
那这个是不是可以证明我们之前说的指针变量p里面装的值为a的地址,这里我们再一次强调一下就是我们的内存单元都有对应的编号,我们把这个编号又称为地址,我们把这个地址有称为指针,那么我们创建一个变量来存储这个变量,我们就称为是指针变量,但是由于简化我们这里一般都叫指针。

4.指针的使用

这里我们再来说说指针的使用,首先我们先想个问题,如果我们知道一个人的经常性的住址,那么我们是不是就可以通过这个地址找到这个人。那么同样的道理,这里我们可以通过这个&操作符得到一个变量a的地址,那么我们是不是就可以通过这个地址找到这个变量a里面的内容,就好比我们知道一个人的住址就可以找到这个人一样,那么对应的来说我们找到了这个地址对应的内容,那我们是不是应该可以对这些值做出一些改变,那么这里我们再来介绍一个操作符叫做解引用操作符*,我们得到了一个地址,那么我们要是想得到这个地址所对应的值的话,那么我们就得使用*,我们来举个例子我们这里创建了一个变量a,然后用一个指针变量p存储他的地址,然后我要是想改变a的值的话怎么改变,当然这时候我们有小伙伴们这时候就要说了,啊这还不简单直接后面写a=你想要的值不就够了嘛,当然这种方法也可以,但是这里我们学到了解引用操作符,那我们是不是就可以用这个操作符来实现我们来看这段代码

#include<stdio.h>
int main()
{
	int a = 10;
	int* p = &a;
	*p = 20;
	printf("%d", a);
	return 0;
}

大家看哈,我们这里得到了a的地址,并且将a的地址存入p中,再解引用p那么我们这里是不是就可以访问到a的数据了,那么我们是不是也就可以通过*p来改变a的数据了,看到这里大家是不是对解引用操作符有了一定的了解,知道了指针是如何来使用的,但是这里我还要讲一个东西就是,大家有没有想过这么一个问题就是一个内存单元的大小是一个字节,而我们的每个内存单元都会对应着一个地址但是我们一个int类型的变量的大小是4个字节啊,那他是不是因为有4个地址呢?对不对?当然这里说的确实没错我们一个int类型的变量他确实有4个地址,但是我们c语言规定了一件事就是我们变量的地址取到的是这四个地址中的首地址,不会说你用取地址操作符一下子取到了四个地址,这是不可能的因为我们变量再申请空间的时候会申请一段连续的空间那么看到这里我们就不再进行扩展因为这部分的内容有点难,我们这里只是初步的进行了解,没必要全部弄明白。

5.指针的大小

我们有许多的类型比如我们之前将的char,short,int,long,long long,float,double,那么这不同的类型是不是也同样的对应着不同的指针类型,那么我们这里就有个问题这些不同的指针类型的大小又是多少呢?因为我们指针变量,他说到底也是一个变量,他这个变量也会像电脑申请空间然后这个空间里面存入地址那么我们这个申请的空间的大小又是多少呢?有同学就要说了,这个指针的大小会不会随着类型的不同,而改变啊!那么这里我们就要聊聊我们之前说的东西了。我们说地址的产生是因为电脑里面内置了32根地址线,而这32根地址线会产生32个2进制的数字,这32个2进制的数字就形成了我们的地址,那么我们这里就因该能够明白,我们这个地址不过怎么变,那么他是不是都应该是这32个2进制的数字,那么我们电脑想要存储这些32个2进制的数字的话,那么是不是所需的空间的大小是一定的,我们之前说过电脑存储一个0或1所需要的空间大小是1bit,那这32个是不是就32bit,而1字节又等于8bit,那么我们存一个地址的大小是不是就是4个字节,也就是说不管你是什么类型的指针,你的大小都是4个字节,当然我们这是在32位的情况下的指针的大小,那要是在64位下呢?那是不是也就对应的应该是8个字节。我们下面来用一段代码来验证这个说法

#include<stdio.h>
int main()
{
	int a = 10;
	short b = 5;
	char c = 'f';
	float d = 1.0f;	
	printf("%d\n", sizeof(&a));
	printf("%d\n", sizeof(&b));
	printf("%d\n", sizeof(&c));
	printf("%d\n", sizeof(&d));
	return 0;

}

这里我们创建了不同类型的变量并且计算了他们的地址所对应的大小,发现都一模一样都是4 个字节
请添加图片描述
想必看到这里大家应该能初步了解了指针这里的最后我得提醒大家一件事情就是我们在创建指针变量的时候有些小伙伴喜欢这么写int* p1,p2,p3其实这里是有问题的这里的*他会被p1给拿走,所以后面的p2,p3是没有*的所以这里的p2,p3也就变成了int型而不是指针。

五.结构体

1.为什么会有结构体

我们之前讲过各种各样的类型比如说char,short,int,long,long long,float,double,但是大家有没有想过这么一个问题就是,我们这么多类型,但是他好像不能创建那么一个变量用来描述一个本书吧,这么多类型的变量但是他好像不能用来描述一个人吧,所以这里我们就发现了一个问题就是我们这里的类型他是不能描述一个复杂的对象的,比如说一个人他是不是有对应的名字,年龄性别地址。我们的一本书他是不是有对应的书名,作者,出版社,和定价,既然这些对象都十分的复杂那我们怎么来描述他们呢?那么我们c语言就给了一个能够自定义类型的能力叫结构体。

2.如何创建结构体

这里我们就要用到一个关键字叫struct,这里我不好讲他的作用是什么但是我这里举个例子让大家感受感受比如说我这里创建一个结构体来描述一个人,那么我们这里就想一个人的话那么应该有对应的名字性别年龄和电话那么这里我们就创建一个结构体

struct student
{

};

这个struct表示的是这是一个结构体,这个student就相当于这个结构体的名字,那我们上面说的各种属性啥名字性别之类的就应该放到这个大括号里面,名字,性别,电话号码我们用字符数组来存储,年龄用int类型来存储,我们把这些不同的类型就放到大括号里面,我们来看代码怎么实现:

struct student
{
	char name[20];
	int age;
	char sex[10];
	char tele[12];
};

那么这里我们的结构体就创建好了,那么这里我们就要用这个结构体创一个变量,比如这里我们创建一个学生s,我们用这个结构体来描述这个s我们来看看如何来实现:

#include <stdio.h>
struct student
{
	char name[20];
	int age;
	char sex[10];
	char tele[12];
};
int main()
{
	struct student s = { "yechaofan", 18, "male", "18571672813" };
	return 0;
}

这里我们就可以看到我们创建了一个变量s,这个变量s的类型是struct student的类型,这里我们注意一下哈,我们这个struct student是一个类型,他就相当于我们之前说的创建一个整形变量a中的int一样。那么我们这个大括号里面就是要存储的内容我们这个要一一对应,我们创建结构体的时候就是按照先name 再 age 再sex 最后是电话的顺序,那我们在创建结构体往里面存入数据的时候也得按照这个顺序,我们的name,sex,tele是创建的就是字符串的类型那我们在输入这个数据的时候是不是也得是字符串的类型,我们的age创建的是整形,那我们输入进去的时候就也得是整形。

3.结构体的使用

我们上面讲了如何创建一个结构体的变量,并且如何往里面存储数据,那么我们这里就来说说如何使用这个结构体变量里面的数据,这里我们就先介绍一个操作符(.)就是这么一个点这个点能调出我们存储的内容,前面是结构体对象,中间加个.然后后面是结构体里面的成员。比如说我们这里想要打印出我们上面的那个例子里面的内容那我们代码是不是应该这么写

#include <stdio.h>
struct student
{
	char name[20];
	int age;
	char sex[10];
	char tele[12];
};
int main()
{
	struct student s = { "yechaofan", 18, "male", "18571672813" };
	printf("name=%s\n age=%d\n sex=%s\n tele=%s\n", s.name, s.age, s.sex, s.tele);
	return 0;
}

当然我们这里的顺序是可以改的,但是有一点就是要注意的就是我们这里的%s,%d要与之对应,不能错位,比如说我们这里的age就不能对应了%s不然就会报错

printf("name=%s\n age=%d\n sex=%s\n tele=%s\n",  s.age, s.name, s.sex, s.tele);

当然我们这里打印结构体内容的方法不止一个,我们再来介绍一个操作符->这个跟上面的那个使用方法差不多,但是我们这个操作符->前面得是结构体的指针变量后面是是成员名,大家这时就会感到十分的疑惑为什么会有这么一个操作符呢?明明一个人可以干的事情,干嘛叫两个人呢?我们来看个例子:

#include <stdio.h>
struct student
{
	char name[20];
	int age;
	char sex[10];
	char tele[12];
};
void print(struct student* ps)
{
	printf("%s %d %s %s \n", (*ps).name, (*ps).age, (*ps).sex, (*ps).tele);
}
int main()
{
	struct student s = { "yechaofan", 18, "male", "18571672813" };
	print(&s);
	return 0;
}

这里我们创建了一个函数,其功能就是打印结构体变量里面的内容,那我们这将结构体的地址传了上去,那么这时我们就得用结构体型的指针来接收,那么我们在打印的时候是不是每次都得解引用,那这是不是就十分的麻烦啊,你看上面的代码每次都要解引用,所以我们这里就有了一个新的操作符用来针对这种指针型的结构体那我们根据前面的所说的写法是不是因该可以进行简化

struct student
{
	char name[20];
	int age;
	char sex[10];
	char tele[12];
};
void print(struct student* ps)
{
	printf("%s %d %s %s \n", (*ps).name, (*ps).age, (*ps).sex, (*ps).tele);
	printf("%s %d %s %s \n", ps->name, ps->age,ps->sex, ps->tele);
}
int main()
{
	struct student s = { "yechaofan", 18, "male", "18571672813" };
	print(&s);
	return 0;
}

大家看一下就行我们这里确实有所简化至少我每次不用写括号,具体的用法就是这,我们后面会进行更加详细的讲解

总结

有一说一我终于把这篇文章写出来了,这个专栏也就结束了,这里说说本人的感触吧,当初搞这个专栏的时候就是考虑到有很多的小伙伴们是第一次学c语言,所以为了那些小伙伴们能够很好的学下去,毕竟我们这里做了一个串通,能够让你知道有这个东西,虽然不一定会用,但是我知道有,这样我们的心里有谱,我这里就做了一个引导,让他们先大致的了解一下,不至于后面详解的时候啥也不懂,所以这三篇文章大家不一定能够学到一些有用的东西,但是我觉得一件事情的开始得有一个好的引导,先了解再一个个攻破,我们后面的c语言入门不见不散到时候我会更加的详细的讲解c语言而且我在写文章之前会提前打个草稿,尽量多一些例子少一点专业术语,这样我觉得能够更好的理解。好就这样把!

评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶超凡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值