计算机萌新的成长历程——初识C语言16

大家好,很高兴又能跟各位朋友见面了,前面我们花了两篇内容来探讨操作符的相关内容,今天咱们要开始探讨新的内容了——常见关键字。

对于常见关键字,我是这样理解的——C语言中自带的可以直接使用的字符,比如咱们的数据类型:int、char、short、long、long long、float、double……又比如咱们的选择语句:if……else if……else,再比如咱们的循环语句:while、for、do……while等等。

我们今天要探讨的关键字是除上述这些关键字外其它的能够供我们在今后写代码的过程中直接使用的,下面咱们来简单介绍一下吧。常见的关键字有:

auto——自动(在局部常量前的关键字通常省略不写);break——打断、终止(1.停止循环2.用于switch语句);case——情况、案例(用于switch语句);char——字符类型;const——恒定不变的(修饰常变量);continue——继续(用于循环);default——默认(用于Switch语句);do——做、执行(do……while语句);double——双精度浮点型;else——否则(if……else语句);enum——枚举(枚举常量);extern——引入外部符号(可以引用其它源文件内部定义的全局变量);float——单精度浮点型;for——for循环语句;goto——goto语句(无条件转移语句);if——if语句;int——整型;long——长整型;register——寄存器关键字(通过请求编译器将变量存在CPU内部寄存器中,而不是通过内存寻址访问以提高访问效率);return——返回;short——短整型;signed——有符号数(int——signed int——有符号的整型);unsigned——无符号数(数字无符号之分,永远为正);sizeof——计算变量/类型/数组所占空间大小;static——静态;struct——结构体关键字;switch——switch ……case语句;typedef——类型定义;union——联合体/共用体;void——无/空;volatile——易变的、不稳定的;while——while循环语句……

*注:关键字不能与变量名冲突

1.关键字typedef——类型定义——类型重定义

怎么去理解这个关键字呢?

对于这个关键字我是这样理解的,咱们现在不是学了七种数据类型吗——char、short、int、long、long long、float、double

我们可以利用typedef来给他们进行重定义一下。换句话说就是给这些数据类型重新起个名字,比如整型它的名字是int,我可以通过typedef给它再起个小名i,这时i就相当于是int,它具有int的性质,我们在使用i时,就像在使用int。下面我们通过代码来验证一下:

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <string.h>

int main()
{
int a;
typedef int i;
i b;
printf("%d,%d,%d\n", sizeof a, sizeof b, sizeof(i));
return 0;
}

我们尝试着运行一下:

这里我们可以看到,不管是变量a、变量b还是字符i所占空间大小都是4,这里我们继续测试i在用sizeof计算大小时是不是和int一样必须带括号:

这里我们看到了系统报错在12/13这两行,也就是说此时的i确实和int一样在计算大小时必须带括号。我们继续看看报错内容会发现12行提示的是1.应输入表达式2.语法错误,13行提示的是1.不允许使用类型名2.“i”将此类型用作表达式非法3.“printf”没有为格式字符串传递足够的参数。这里我们可以得到几个结论:

1.在用typedef给类型重定义/重命名后,新的字符串就是该类型的名称;

2.定义完后不管是单个字符还是多个字符,此时它的本身的性质是字符串。

这里我们可以确定typedef的用途,它是为了将类型名称重命名,让我们使用的更加简单顺手一点,使用的方式如下:

代码语言:javascript
复制
typedef 类型名 重命名;//1.三者中间用空格隔开2.命名完后的分号别掉了;

2.关键字static——静态

这个静态指的是什么静态呢?这里我的理解是原本很活跃的对象,在使用static后就安静下来了。感觉更不好理解了对吧,这个活跃指的是什么,这个安静又是指什么?在解释这些问题之前,我们先探讨一下它的用法:

1.static修饰局部变量——加长局部变量的生命周期

2.static修饰全局变量——限制了全局变量的作用域

3.static修饰函数——改变了函数的链接属性

这里我们可以看到使用static时提到了三个对象——局部变量、全局变量及函数。在前面的内容里,我分别分享了自己对这三个内容的理解。有兴趣的朋友可以回顾一下初识C语言4、和初识C语言12,这里我就不多做解释了。下面我们来对这三个用法一一探讨:

1.static修饰局部变量——加长局部变量的生命周期

通过前面的分享,我们知道局部变量的生命周期是在对应的代码块内也就是大括号{}内,出了对应的大括号,它的生命就结束了,这里我们要提到一个关键字来帮助我们更好的理解——auto——自动,在创建局部变量时,这些局部变量是在大括号内自动创建自动销毁的,比如int a = 10;这里的局部变量a就是自动创建自动销毁,出了大括号,他就不存在了,下面我们通过代码来验证一下:

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <string.h>

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

这里我们在函数中创建了一个局部变量a,我们在主函数中调用这个函数,或者换一种说法是将我们在源文件内部创建的test这个函数进行内部链接,使它能在这个源文件内部使用,那下面问题来了,我们运行后的结果会是 什么呢?如图所示:

这里我们可以看到,结果打印出来是三个a=2,这说明了我们每次调用test函数时,a都是从a=1开始的,然后进行a++,再打印,一直重复到跳出循环。那说明在一次循环过后,a是自动消失了,然后再进入循环后它又在函数内自动创建了这个创建的过程就是

int a = 1;这里我要说明的是在局部变量前面我们省略了一个关键字auto,也就是说,这里的局部变量完整的代码是auto int a =1;所以局部变量我们也可以称为自动变量。这里也很好的印证了局部变量是自动创建自动销毁的。如果我们在局部变量a的前面加一个static关键字,结果又会如何呢?如下图所示:

这里我们可以看到,此时的a在被static修饰后,它在出了大括号后不再自动销毁了,还是能继续存在,所以第二次进入循环时,它是a=2,a++,打印a=3,第三次进入循环时,它是a=3,a++,打印a=4,这里我们发现,它的生命周期已经不再局限大括号了,被static给加长了。这里我们就印证了它的第一个作用:static修饰局部变量时,能加长局部变量的生命周期;

2.static修饰全局变量——限制了全局变量的作用域

从前面的分享,我们知道了全局变量的作用域是跟随整个工程的,我们的一个工程中可能不止存在一个项目,这里我们要拓展一下全局变量的一个新的内容,为什么说它的作用域是整个工程而不是项目,这里我们创建一个新的项目test3-1.c来验证一下,如图:

这里我们在新建项目中定义了一个整型全局变量a,并将10赋值给了a,那我希望在项目test3.c中应该如何使用这个变量呢?这里我们就要提到一个新的关键字extern——引入外部符号(可以引用其它源文件内部定义的全局变量),这里我们试着将全局变量a引用到test3.c这个项目中并打印:

这里我们可以看到能够正常使用并打印,这个结果进一步说明了全局变量的作用域是整个工程,只不过在不同项目之间需要使用的话需要用到关键字extern——引入外部符号,那如果我们给全局变量a前面加上static,结果又会如何呢?

这里我们可以看到,在增加static后,我们发现,我们想在test3.c中引用这个全局变量时,系统报错,无法解析外部符号,那说明此时的全局变量a不能继续被引用了,也就是说它的作用域被限制了,下面我们尝试着在它自己所在的项目内看能不能打印,这里要说明一个问题,一个工程内只能有一个main函数,这里如果我们直接使用main函数,系统会报错:

这里也进一步验证了在C语言中,计算机的入口main函数有且只能有一个,这里我们把test3.c中的main函数注释掉,再进行操作:

可以正常运行,这里说明了全局变量在被static修饰后只是作用域被限制了——原本是作用于整个工程,现在被限制在自己所处的工程内,对全局变量本身是没有影响的,在自己所处的项目内还是能够正常使用。通过上面的测试,我们验证了static的第二个作用:static在修饰全局变量时,会限制全局变量的作用域;

3.static修饰函数——改变了函数的链接属性

通过前面的分享,我们学会了如何使用自定义函数,这里我们要拓展函数的一个知识点——链接属性,什么是函数的链接属性?这里我是这样理解的,我在编写博客的时候会引用一些我自己搜索的资料,这时我为了让大家能够看到这份资料时,我会在相应的字上创建链接,并将资料的网址填入其中,这样大家都能通过这个链接来找到这些资料了,所谓的链接就相当于一个传送门,我们在讲述自定义函数的时候有提到过在main函数的外部来定义函数,在main函数的内容通过输入自定义函数的代表字符就能调用他,这是不是就跟传送门是一个性质,自定义函数的代表字符就是自定义函数的传送门,我们通过这个传送门来调用这个函数。这里我们是在同一个项目内能够这样去做,那如果我在其它项目内能不能正常调用呢?我们来测试一下:在test3-1.c中自定义一个两数相加的函数,在test3.c中通过关键字extern来调用,看看能不能行:

我们创建了add这个自定义函数,接下来在test3.c中通过extern来进行调用,这里要注意调用的格式:

代码语言:javascript
复制
extern 自定义函数的字符(变量类型,变量类型);//这里通过extern来对外部函数进行声明;
//完成声明后进行正常的调用;

这里我们可以看到,add函数在被声明后可以很好地使用,通过这里我们可以总结以下函数的链接属性,函数不仅拥有内部链接属性,能够在自己所处的项目内正常调用,还拥有外部链接属性,在不同项目内通过extern关键字来声明外部函数,以此来进行正常的调用。

接下来我们试一下在自定义函数前加入static,看看会出现什么结果:

这里我们可以看到,函数add无法正常被调用,那说明被static修饰后,函数add失去了它的外部链接属性,下面我们测试一下它的内部链接属性有没有受到影响:

函数在所处的项目内正常被调用,并无任何影响,说明函数在被static修饰后函数自身的链接属性被改变了,函数失去了它的外部链接属性,这里我们通过测试验证了static的第三个作用:static在修饰函数时,会改变函数的链接属性。

对于关键字的内容我们分享到这里,其它的关键字,我会在后续的学习过程中继续给大家分享,下面我们来对今天的内容做个总结:

1.关键字typedef——类型重定义,是可以将类型重新命名,不会改变类型的用法,我们可以通过typedef重命名类型后让自己使用的更加顺手;

2.关键字static——静态,它有3种用法;

(1)static修饰局部变量——静态局部变量——局部变量的生命周期被加长了,由原先的在相应代码块内开始到结束变成了可以跟随整个项目的开始到结束;

(2)static修饰全局变量——静态全局变量——全局变量的作用域被限制了,由原先的作用于整个工程变成了作用于所处项目;

(3)static修饰函数——静态函数——函数的链接属性被改变了,由原先的拥有内部链接与外部链接两种属性变成了只拥有内部链接属性。

3.关键字auto——自动,所有的局部变量都是自动变量,会自动产生和销毁,我们在编写代码的过程中会省略auto关键字;

4.关键字extern——引入外部符号,可以将其他项目内的全局变量、自定义函数引入到当前项目中进行使用、

我们今天的内容到这里就结束了,希望本篇内容对大家在理解这些关键字的使用上会有帮助,随着接下来的学习的深入,我会继续分享在学习过程中的感受,感谢各位朋友的翻阅,咱们下一篇见。