第二讲:(一)数据类型和变量

数据类型

第一讲中提到一个词语叫返回类型,其中的类型在C语言中有很多的分类,用来描述生活中的各种数据。

C语⾔提供了丰富的数据类型来描述⽣活中的各种数据。 使⽤整型类型来描述整数,使⽤字符类型来描述字符,使⽤浮点型类型来描述⼩数。

所谓“类型”,就是相似的数据所拥有的共同特征,编译器只有知道了数据的类型,才知道怎么操作 数据。

下⾯盘点⼀下C语⾔提供的各种数据类型。

 字符型

1        char

2        [signed] char

3        unsigned char

整形

1         //短整型

2        short [int]

3        [signed] short [int]

4        unsigned short [int]

5

6        //整型

7        int

8        [signed] int

9        unsigned int

10

11        //长整型

12        long [int]

13        [signed] long [int]

14        unsigned long [int]

15

16        //更长的整型

17        //C99标准中引入

18        long long [int]

19        [signed] long long [int]

20        unsigned long long [int]

浮点型

1        float

2        double

3        long double

 布尔型

在C语言中,C99标准以前并没有为布尔值设置专门的类型,而是使用整数0标示布尔值假,非零则标示布尔值的真。

在C99标准以后,引入了布尔类型,专门标示真假。

1        _Bool

 和其他的类型不同,布尔类型的使用需要引入头文件<stdbool.h>才可以使用。否则会引起报错。

布尔类型变量的取值是:true或者flase。

我们在VS中定义一个布尔类型的变量,然后左键选取bool类型名称,右键点击这个类型,选取转到定义这个选项中,如下所示:

#define bool  _Bool
#define false 0
#define true  1

从上面的代码中我们看出, false被定义为0 , true被定义为1。这和刚才我们所说的C语言中0为假,非零为真基本吻合。

代码演示:

#include <stdbool.h>
#include <stdio.h>

int main()
{
	bool a = true;
	bool b = false;
	if (a)
	{
		printf("真");
	}
	if (b)
	{
		printf("假");
	}
	return 0;
}

演示效果:

 数据类型的长度

每⼀种数据类型都有⾃⼰的⻓度,不同的数据类型,所创建出的变量⻓度不同,存储的数据范围就有所差异。这里的长度代表的则是这个变量在内存中所占用的空间,单位为字节。

sizeof操作符

sizeof是一个关键字,同时他还是一个操作符,专门用来计算数的类型长度的。

sizeof操作符的操作数可以是类型,也可以是变量或者表达式。

1        sizeof(类型)

2        sizeof 表达式

sizeof的操作数如果不是类型,是表达式的时候,可以省略后边的括号的。

sizeof后边的表达式不真实参与运算的,根据表达式的类型得出大小。

sizeof计算结果是size_t的类型。

        sizeof 运算符的返回值,C 语⾔只规定是⽆符号整数,并没有规定具体的类型,⽽是留给 系统⾃⼰去决定, sizeof 到底返回什么类型。不同的系统中,返回值的类型有可能是 unsigned int ,也有可能是 unsigned long ,甚⾄是 unsigned long long , 对应的 printf() 占位符分别是 %u 、 %lu 和 %llu 。这样不利于程序的可移植性。 C 语⾔提供了⼀个解决⽅法,创造了⼀个类型别名 size_t ,⽤来统⼀表⽰ sizeof 的返 回值类型。对应当前系统的 sizeof 的返回值类型,可能是 unsigned int ,也可能是 unsigned long long 。

int main()
{
	int a = 0;
	printf("%zu\n", sizeof(a));
	printf("%zu\n", sizeof a);
	printf("%zu\n", sizeof(int));
	printf("%zu\n", sizeof (3.5+6));
	return 0;
}

运行结果如下:

 数据类型长度

       

#include <stdio.h>
int main()
{
	printf("%zu\n", sizeof(char));
	printf("%zu\n", sizeof(bool));
	printf("%zu\n", sizeof(short));
	printf("%zu\n", sizeof(int));
	printf("%zu\n", sizeof(long));
	printf("%zu\n", sizeof(long long));
	printf("%zu\n", sizeof(float));
	printf("%zu\n", sizeof(double));
	printf("%zu\n", sizeof(long double));
	return 0;
}

在X64中输出结果如下:

对应数值如下所示:

 

 下面代码是为了验证sizeof是不计算其中的表达式:

//测试:sizeof中表达式不计算

#include <stdio.h>
int main()
{
	short a = 2;
	int x = 10;
	printf("%zd\n", sizeof(a = x + 3));
	printf("a =%zd\n", a);
	return 0;
}

输出结果为:

我们已知short类型的值长度为2,int类型的长度为4,a在sizeof中如果计算的话应被重新赋值为13,但是第一个输出的值却为2,这个2就是short类型长度。sizeof在代码进行编译的时候,就已经根据表达式的类型决定了其值的大小,而表达式的执行是要在程序运行中才会执行,在编译期间已经被sizeof处理掉了,所以在运行期间就不会执行表达式了。

signed 和 unsigned

在C语言中,signed和unsigned关键字用来修饰字符型和整型类型的。

signed 关键字,表⽰⼀个类型带有正负号,包含负值,一般在定义整型变量时,该关键字基本省略,所以在使用short、int、long、long long默认是带有符号类型变量,即可表达数值的正负数。例如 signed int a 等同于 int a;;

unsigned关键字,表⽰该类型不带有正负号,只能表⽰零和正整数,该关键字是不能省略的。

用unsigned的好处是,其定义的变量最大值比 signed定义的变量大了一倍,至于为什么大于一倍,我们在后面会有介绍。

⽐如,16位的 signed short int 的取值范围是:-32768~32767,最⼤是32767;⽽ unsigned short int 的取值范围是:0~65535,最⼤值增⼤到了65,535。32位的 signed int 的取值范围可以参看 limits.h 中给出的定义。

字符类型 char 也可以设置 signed 和 unsigned 。

1        signd char c; // 范围为 -128 到 127

2        unsigned char c; // 范围为 0 到 255 

注意,C 语⾔规定 char 类型默认是否带有正负号,由当前系统决定。

这就是说, char 不等同于 signed char ,它有可能是 signed char ,也有可能是 unsigned char 。

这⼀点与 int 不同, int 就是等同于 signed int。

数据类型的取值范围

上述的数据类型很多,尤其数整型类型就有short、int、long、long long 四种,为什么呢?

其实每⼀种数据类型有⾃⼰的取值范围,也就是存储的数值的最⼤值和最⼩值的区间,有了丰富的类 型,我们就可以在适当的场景下去选择适合的类型。

如果要查看当前系统上不同数据类型的极限值:

     •   limits.h ⽂件中说明了整型类型的取值范围。

     •   float.h 这个头⽂件中说明浮点型类型的取值范围。

为了代码的可移植性,需要知道某种整数类型的极限值时,应该尽量使⽤这些常量。 • SCHAR_MIN , SCHAR_MAX :signed char 的最⼩值和最⼤值。

• SHRT_MIN , SHRT_MAX :short 的最⼩值和最⼤值。

• INT_MIN , INT_MAX :int 的最⼩值和最⼤值。 • LONG_MIN , LONG_MAX :long 的最⼩值和最⼤值。

• LLONG_MIN , LLONG_MAX :long long 的最⼩值和最⼤值。

• UCHAR_MAX :unsigned char 的最⼤值。

• USHRT_MAX :unsigned short 的最⼤值。

• UINT_MAX :unsigned int 的最⼤值。

• ULONG_MAX :unsigned long 的最⼤值。

• ULLONG_MAX :unsigned long long 的最⼤值。

变量 

变量的创建

上面讲了那么多关于类型的介绍,还有数据的各种分类,是用来做什么的呢?它是用来创建变量的。

我们前面也提到了很多次变量,什么是变量呢?在C语言中,经常变化的值被称为变量,固定不变的值被称为常量。

变量创建的语法形式是这样的:

 下图示例:

int a;
short b;
float c;
double d;

我们平常定义变量时是不会这样简单的定义一下就完了,因为这样可能会发生灾难性的问题,如下图:

int a = 0;
short b = 0;
float c = 0.0f;
double d = 0.0lf;

变量在创建时要给予一个初始值,这就是常说的初始化。如上示例中, a被定义为int类型的整型变量,单个=号在C语言中被叫做赋值符号,a被赋予0的初始值。

而变量c和变量d后面添加的f和lf,是定义浮点数时候用到的。如果我们不给与一个初始值,那么变量里面存储的数值将会是个随机值,那么此时在没有赋值的情况下去调用这个变量,后果是不可预计的!

变量的分类

变量分为全局变量局部变量

        • 全局变量:在大括号外部定义的变量就是全局变量  

        全局变量的使用范围更广,整个工程中想使用,都是有办法使用的。

        • 局部变量:在大括号内部定义的变量就是局部变量        

        局部变量的使用范围是比较局限,只能在自己所在的局部范围内使用的。

#include <stdio.h>
int glocal = 13;

int main()
{
	int local = 14;
	printf("%d\n", glocal);
	printf("%d\n", local);

	return 0;
}

 

上面代码中我们看到, glocal变量是在main()函数外定义的,可是在main()函数中任然能够正常使用。如果全局变量和局部变量的命名一样会发生什么呢?我们对上面代码做一下修改:

#include <stdio.h>
int local = 13;

int main()
{
	int local = 14;
	printf("%d\n", local);
	return 0;
}

 

代码修改后,运行发现,虽然名称同样的,但是它并没有报错,而且还正常运行了,其值是main()函数中赋予的值。

其实当局部变量和全局变量同名的时候,局部变量优先使用。

全局变量和局部变量在内存中存储在哪里呢?

⼀般我们在学习C/C++语⾔的时候,我们会关注 内存中的三个区域:栈区、堆区、静态区。

        1. 局部变量是放在内存的栈区

        2. 全局变量是放在内存的静态区

        3. 堆区是⽤来动态内存管理的(后期会介绍)

其实内存区域的划分会更加细致,以后在操作系 统的相关知识的时候会介绍。

 局部变量和函数参数是存放在栈区的,这部分数据在调用完成以后将会自动销毁,而静态区里面的全局变量和静态变量,只有在程序停止或退出运行的时候才会销毁。

本博客只为学习使用,如有错误请大家指出,感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值