【C语言】第一章:初识C语言(二)

目录

三、变量与常量

(一)定义变量的方法

(二)变量的命名

        1.变量命名原则

        2.经典的错误,标准的零分

        3.变量的分类

        4.变量的定义域与生命周期

        5.常量

四、字符串与转义字符

(一)字符串

        1.定义

        2.字符串的结束标志

        3.字符串在数组中的存储

        4.字符串的长度

(二)转义字符

        1.定义

        2.常见转义字符

        3.比较:字符 '0',数字 0,字符 '\0'

总结


三、变量与常量

(一)定义变量的方法

int main ()
{
    int a = 150;
    float b = 15.5f;
    char ch = 'w';
    return 0;
}

如上所示,类型加自定义的名字,同时给其赋值,即为定义变量。

(二)变量的命名

        1.变量命名原则

        (1)只能由字母(包括大写和小写)、数字和下划线( _ )组成。

        (2)不能以数字开头。
        (3)长度不能超过 63 个字符。
        (4)变量名中区分大小写的。
        (5)变量名不能使用关键字。

        2.经典的错误,标准的零分

        int #ac    //违背规则1,使用了#
        int 2b     //违背规则2,使用了数字开头
        int char   //违背规则5,使用了关键字

        3.变量的分类

变量分为:局部变量和全局变量

区分方法:判断其位置,若在大括号外,则为全局变量;反之,则为局部变量

#define _CRT_SECURE_NO_WARNINGS
int a = 10;//全局变量

int main() 
{
	int b = 20;//局部变量
	return 0;
}

int c = 30;//全局变量

 但是,如果若出现以下情况

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

也就是说,局部变量和全局变量名字冲突,此时遵循:局部优先原则。

 运行结果如下

 小贴士:

        尽量少使用局部变量

        避免局部变量和全局变量冲突

        4.变量的定义域与生命周期

                (1)作用域

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

                         ①局部变量的作用域是局部变量所在的局部范围

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

上述代码,编译时报错。a出了这个大括号,就会被销毁。

                        ②全局变量的作用域是整个工程

 上述代码中,a的生命周期都是整个工程文件。

 这里先说明一下extern

 extern——声明同一个工程项目中的外部变量。

        如上所示,在一个工程中创建了两个.c文件,在Test2.c中定义了一个变量,然后在Test.c中,使用extern这个关键词,来声明变量a,这个时候就能在Test.c这个文件中使用a这个变量了

                         ③几个经典的错误,标准的零分

初级阶段,我们可能会由于概念不清,学识尚浅,导致了很多奇葩的错误。在这里我列举几个经典的错误

Ⅰ.如下所示,声明变量放在使用后面,这是个典型的因果倒置错误。代码首先经过编译以后才能运行,在编译的时候,我们的代码在test函数中的a还没有声明,就已经被使用。由此导致编译错误。

#include<stdio.h>
void test()
{
	printf("test:%d\n", a);
}
int a = 2022;//定义
 
int main()
{
	printf("%d\n", a);
	test();//调用
	return 0;
}

Ⅱ.如下所示,一个printf不在任何一个函数体里面,在运行的过程中根本不会调用这个函数。

#include<stdio.h>
int g_a = 2022;//定义
 
void test()
{
	printf("test:%d\n", g_a);
}
int g_a = 2022;//定义
printf("%d", g_a);//Attention!
int main()
{
	printf("%d\n", g_a);
	test();//调用
	return 0;
}

                        ④声明和定义的区别

上文中提及了很多名词,有时候说定义,有时候说声明,那这两有区别吗

肯定有。那区别在哪呢?

给出一段代码,来区分一下

int a;//声明
 
void test()
{
	printf("test:%d\n", a);
}
int a = 2022;//定义
 
int main()
{
	printf("%d\n", a);
	test();//调用函数
	return 0;
}

在这段代码中,第七行,int a = 2022;时,称作定义。无论这个定义靠前还是靠后,都被称作定义,但是可能会出现一个问题,变量a定义在使用的后面,这个时候编译器会直接报错。为解决这种情况,在第一行补上int a;但是没有赋值,此时,称作声明。

即:声明是为了防止编译器报错,先声明一下,我有这个变量存在,但具体值是什么,没定,在后面对其定义。当然,把定义放在第一行的话,此时的定义同样有声明的功能。

                (2)生命周期

变量的生命周期,指的是变量创造到变量销毁之间的时间段

        ①局部变量的生命周期:进入作用域生命周期开始,出作用域生命周期结束

        ②全局变量的生命周期:整个程序的生命周期

        5.常量

                (1)常量的分类

常量分为以下四类:

                ① 字面常量

                ② const修饰的常变量

                ③ #define修饰的标识符常量

                ④ 枚举常量

                (2)字面常量

#include<stdio.h>
int main()
{
    //1           整数字面常量
	//300         整数字面常量
	//3.14        浮点数字面常量
 	//'a'         字符字面常量
	//"abcjdksa"  字符串字面常量
 
	return 0;
}

                (3)const修饰的常变量

对于这个const修饰的常变量,很多人都比较疑惑,这名字起得比较奇怪,到底是什么意思呢,其实,“常变量”,常是修饰词,是由const进行修饰的,变量才是主语。

也就是说,const修饰的常变量,首先是一个变量,只不过由于const修饰,给其赋予了常属性(不可改变)。具有变量的一些性质

#include<stdio.h>
int main()
{
	const int num =100 ;
	num = 200;
	return 0;
}
 

 如上所示,在这里,我们已经用const修饰num了,如果我们还想要强迫改变num,对不起,编译器报错。

这也是个经典的错误,标准的零分,许多新手玩家都会在这里被坑。

                (4)#define修饰的标识符常量

#define M 200
#include<stdio.h>
int main()
{
	int a[M] = { 0 };
	printf("%d", M);
	M = 100;
    return 0;
}

如上所示,使用define将M全部替换成200,注意,define这条指令是在预处理阶段进行的,将所有M全部替换成200。

我们知道,数组内元素的个数,是一个常数,调试没问题,这说明M本质上是一个常数。第二条语句中打印M,结果为200,这说明M被替换成200。第三条语句中想要强行修改M的值,抱歉,编译器报错。这再次说明,M是一个常数,具有常数性,不可被修改。

                (5)枚举常量

这个概念,我们在数学中遇见过类似的,数学中有一种是枚举法,一般用于计算古典概型。

枚举在c语言中也是一样的,表示一一列举。跟数学的古典概型有区别的是,数学中的古典概型是有限个 ,或者是无限可列的但必须满足某种规律下(比如几何分布,巴斯卡分布等)。而我们c语言中的枚举仅仅代表前者,是有限个。比如血型,性别,三原色等等。
枚举的标识符是enum

#include<stdio.h>
enum Color {
	RED,//0
	//RED,GREEN,BLUE是枚举类型Color的可能取值,同时也是常量,所以叫枚举常量
	GREEN,//1
	BLUE//2
};
int main()
{
	enum Color c = BLUE;
	printf("%d\n", RED);
	printf("%d\n", GREEN);
	printf("%d\n", BLUE);
	printf("%d", c);
}

如上代码所示,定义一个枚举类型,并执行语句,输出结果分别为0,1,2,2,这说明枚举常量中第一个被默认赋值为0,后面依次递增1。

关于枚举常量,后文还会有详细介绍,此处按下不表。

(6)经典的错误,标准的零分 

①define 定义标识符常量后额外加了分号,有很多人在这块掉入了坑里,其实这块是不需要加分号的
②对const修饰词理解不够到位,误以为常变量是一个常量。我们知道,定义数组时的长度为一个常量,如果是变量则会报错,理论存在,实践开始。

 如图所示,“表达式必须含有常变量”,证明完毕,M不可以使用在数组上,因为M本质是一个变量。

四、字符串与转义字符

(一)字符串

        1.定义

“Hello World.\n”

形如这种,由双引号引起来的一串字符,被称为字符串字面值,或者简称字符串

        2.字符串的结束标志

字符串的结束标志是一个叫“ \0 ”的转义字符。在计算字符串长度时候\0是结束标志,不算做字符串内容

        3.字符串在数组中的存储

请思考,以下代码输出结果是??

#include<stdio.h>
int main()
{
	char arr1[] = "hello";
	char arr2[] = { 'h','e','l','l','o' };
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	return 0;
}

运行结果如下

 

为什么会第二个数组会出现这种情况呢?
字符串的结束标志是\0,第一个数组中,由于字符串常量默认最后一个是\0,所以可以正常打印。而对于第二个就比较糟糕了,因为他是一个字符一个字符输入进去的,这就导致了他的后续可能还有一堆其他乱七八糟的东西,也会一直打印出来,直到出现第一个\0。
 

 这是监视窗口里的数据,再次验证了字符串在数组中的存储

        4.字符串的长度

 c语言中提供了一个库函数,叫做strlen,这个函数可以计算字符串的长度,统计的是\0之前的字符个数。strlen------string lenth ,属于string这个库中。

#include<stdio.h>
int main()
{
	char arr1[] = "abc";
	char arr2[] = { 'a','b','c' };
	printf("%d\n", strlen(arr1));
	printf("%d\n", strlen(arr2));
}

 运行结果如下,

 原因为,第一个数组末尾默认有一个\0,而第二个数组末尾并没有\0,又字符串的结束标志是\0,因此,编译器会一直往后计算,直至\0出现,故第二个数组的长度是一个随机值。

(二)转义字符

        1.定义

先来看这两段代码

#include<stdio.h>
int main()
{
	printf("abcdnf");
	return 0;
}
#include<stdio.h>
int main()
{
	printf("abcd\nf");
	return 0;
}

输出结果分别为

 

此时,由于这个\n,导致了原本n的意思发生转变。

转义字符,就是将原来的字符的意思转变。 

        2.常见转义字符

转义字符释义

\?

在书写连续多个问号时使用,防止他们被解析成三字母词
\'用于表示字符常量'
\''用于表示一个字符串内部的双引号
\\用于表示一个反斜杠,防止它被解释为一个转义序列符。
\a警告字符,蜂鸣
\b

退格符

\f进纸符
\n换行
\r回车

\t

水平制表符
\v垂直制表符
\dddddd表示1~3个八进制的数字。如:130 X
\xdddd表示两个十六进制数字。如:\x30

接下来详细讲解一下比较重要的转义字符

(1)转义字符  \?

这个转义字符,主要是避免三字母词使用的,那什么是三字母词呢。这里给出一段代码。

int main()
{
	//    ??) - 三字母词 - ]
	printf("(are you ok??)");
 
	return 0;
}

在一些编译器上会将??)这个转变成  ] 这个字符
为了避免这种情况,我们可以使用\?这个转义字符

(2)转义字符  \' \'' \\ 

这三个转义字符的作用是在想要打印出'  "  \这三种字符时候,用来表达这些字符

#include<stdio.h>
int main()
{
	//printf("%c\n", ''');
	printf("%c\n", '\'');
	//printf("%c\n", '"');
	printf("%c\n", '\"');
	return 0;
}

如上述代码所示,只有加上转义字符,才能正常运行

(3)转义字符 \ddd \xdd

这两个转移字符跟其他的转义字符有些区别
\ddd这个转义字符中,他会将后面的1~3个八进制数字先转换成十进制数字,然后在ASCII表中找到对应的字符。这个字符就是最终的结果
同理
\xdd这个转义字符也是将后面的2个十六进制数先转换成十进制数,然后在ASCII表中找出对应的字符。这个字符就是最终的结果。
先附上ASCII表

ASCII码_holler kite的博客-CSDN博客

#include<stdio.h>
int main()
{
	printf("%c\n", '\077');//077是8进制数字
    printf("%c\n", '\x46');
	return 0;
}

下面给道练习题,请写出下列代码的输出结果

#include <stdio.h>
int main()
{
	printf("%d\n", strlen("abcdef"));
	printf("%d\n", strlen("c:\test\628\test.c"));
	return 0;
}
 

        3.比较:字符 '0',数字 0,字符 '\0'

'0'的ASCII值为48
0和'\0'本质一样,只是同一种东西的不同表现形式,0是数字形式,'\0'是字符形式

总结


本节主要讲述了,变量,常量,字符串以及转义字符等知识点的讲解。
请别忘了留下点赞关注收藏哟

 另,本文所有代码均已上传至gitee,有需要的小伙伴们请自取呐

苍茫远行者:

本站未完,欲知后事,请看下节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值