C语言之《数据类型和变量》

数据类型介绍

在C语言中分为内置数据类型自定义数据类型,这次介绍的是内置数据类型

内置数据类型分为:整型类型浮点型类型字符类型布尔类型

使用整型来描述整数,字符类型描述字符,浮点型描述小数。

类型:相似的数据拥有共同的特征,编译器只有知道了数据类型,才能知道怎么操作数据。

按照顺序,上面介绍类型的种类顺序,来讲解数据类型,我们从整型来介绍。

整型类型

整型就是十进制的整数,整型分为:整型短整型长整型更长的整型

//短整型
short [int]
[signed] short [int]
unsigned short [int]

//整型
int
[signed] int   //有符号整型
unsigned int  //无符号整型

//长整型
long int 
[signed] long int
unsigned long int

//更长的整型
//更长的整型由C99标准中引入
long long int
[signed] long long int
unsigned long long int

其中[ ]中数是可以省略的 ,比如short [ int ] , 我们可以写成short。

例子:
使用int类型创建一个变量,那么变量的数据类型就是整型。

#include <stdio.h>
int main()
{
	int a = 0;
	return 0;
}

在这里插入图片描述
上述我们打印的a为变量,而变量的数据就是整型类型(int) , 打印整型类型的变量,我们则需要用到 %d,%d是整型的打印格式,C语言中也叫占位符,这个本篇中不多叙述,读者朋友现在知道%d叫占位符就好。

而不同的数据类型 , 也需要用到不同的占位符去打印 。

浮点型类型

C语言中浮点型,简单来说就是小数。

浮点型分为 floatdouble 两种。

一般我们默认创建的浮点型就是double类型的。

float  //单精度浮点型
double  //双精度浮点型
long double

例子:

#include <stdio.h>
int main()
{
	float a = 12.1;
	double b = 13.1;
	printf("%f\n", a);
	printf("%lf", b);
	return 0;
}

在这里插入图片描述

为什么打印出来的会是“12.100000” 和 “13.100000”?上述打印int类型的时候,我们创建的变量赋值为0,打印出来的变量就是0,而浮点型的打印却和我们赋值给a和b的值不同?

我们知道float和double是浮点型,是带小数点的,因为浮点数小数点默认有后六位的数,我们打印任何数,编译器打印出来的数都是小数点有6位数。

比如:

#include <stdio.h>
int main()
{
	float a = 9.1;
	double b = 10.1;
	printf("%f\n", a);
	printf("%lf\n", b);
	return 0;
}

在这里插入图片描述
这次随着数的变化,打印的数也随着变化了 , 小数点后面还是会有6位数。

那么我们可不可以省略掉多余的数,只打印我们想打印的值呢?,是可以的 ,小数点后的数是可以限定的的,比如我们打印12.34,只让他打印出12.34,其余后4位省略掉。

我们只需要在打印格式%f的中间加上一个 .2.

#include <stdio.h>
int main()
{
	float a = 12.34;
	printf("%.2f\n", a);
	return 0;
}

在这里插入图片描述
上述我们也说过浮点型分为:floatdouble,那么他们的打印格式也是不一样的,例子中我们打印用到了 %f%lf ,其中 %f是打印float类型的,%lf则打印double类型

字符类型

char
[signed] int
unsigned int

字符类型我们分为: 字符类型字符串类型

我们区分字符类型和字符串类型 , 单引号内的是字符类型 ,双引号内的是字符串类型。

#include <stdio.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = {'a', 'b', 'c', 'd', 'e', 'f'};
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	return 0;
}

字符串末尾默认有一个\0,而\0是字符串的结束标志遇\0字符串就结束打印 ,但\0是隐藏在字符串的末尾的的。

%s是打印字符串的,遇到\0就停止打印。
在这里插入图片描述

字符中是没有\0的,如果你不手动配置上给\0的话,字符中是不会有\0的。

而有\0和没有\0打印的区别是什么?
在这里插入图片描述
当字符中没有\0 ,是会一直打印下去的,直到遇到\0就停止打印,而遇到\0之前会打印什么,我们是不得而知的 , 会打印一些随机值。

当我们在字符类型的后面手动添加上\0。

#include <stdio.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = {'a', 'b', 'c', 'd', 'e', 'f','\0'};
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	return 0;
}

在这里插入图片描述
我们说%s遇到\0就停止打印,真的是这样吗,我们用一段代码来示范一下。

#include <stdio.h>
int main()
{
	char arr[] = "abcd\0ef";
	printf("%s", arr);
	return 0;
}

在这里插入图片描述
我要求的是打印abcdef ,而值输出了abcd , 也由此证明,在%s中只要遇到\0就停止打印。

布尔类型

C语言中原本是没有布尔类型的,也没有为布尔类型单独设置一个类型,而是使用整数.0表示假,非零表示真,布尔类型是C99标准引入的布尔类型后,专门用来表示真假。

_Bool

要使用布尔类型要包含头文件: <stdbool.h>

布尔类型的变量的取值是:truefalsetrue表示真 , false表示假

a为真打印haha,为假什么都不打印。

#include <stdio.h>
#include <stdbool.h>
int main()
{
	_Bool a = true;
	if (a)
	{
		printf("haha");
	}
	return 0;
}

在这里插入图片描述
为真打印,为假则不打印。

当a为真打印haha,为假则打印hehe

#include <stdio.h>
#include <stdbool.h>
int main()
{
	_Bool a = false;
	if (a)
	{
		printf("haha");
	}
	else
		printf("hehe");
	return 0;
}

在这里插入图片描述
需要注意的是,当我们使用布尔类型的时候,一定要包含头文件

使用布尔类型的时候,—Bool和bool都是可以正常使用的。


```#include <stdio.h>
#include <stdbool.h>
int main()
{
	bool a = true;
	if (a)
	{
		printf("haha");
	}
	return 0;
}

在这里插入图片描述

signed 和 unsigned

上面我们介绍整型类型和字符类型的时候都有 signed 和 unsigned,那么 signed 和 unsigned是什么意思呢?

signed 关键字,表⽰⼀个类型带有正负号,包含负值;
unsigned 关键字,表⽰该类型不带有正负号,只能表⽰零和正整数。

注:C 语⾔使⽤ signed 和 unsigned 关键字是修饰字符类型和整型类型的

在这里我给读者朋友补充一个知识点,什么是、关键字。

什么是关键字

关键字是C语言保留下来的一些名字的符号,⽐如: int 、 if 、 return ,这些符号被称为关键字, 关键字也叫保留字

-关键字都有特殊意义,是保留给C语言使用的;
-在创建变量或者标识符时,名字不能和关键字一样;
-关键字不能被创建

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

整型中的signed 和 unsigned

对于int类型默认自带正负数,也就是说int类型默认为signed int
像int类型这种特殊的情况,在我们使用signed int时,不写signe也不会错。

signed int a ;
//等同于int a

当int值表示零和正整数时,就要带上unsigned

unsigned int a;

整型类型定义为unsigned int的好处在于,相比于int,unsigned int同样⻓度的内存能够表⽰的最⼤整数值,unsigned int能表示的最大整数值比int(signed int)大。

int的取值范围可以查看<limits.h>给出的定义。
在这里插入图片描述
我们说括号中的值是可以省略的,signed int 里面的int也可以省略 , 那么我们的变量声明可以这样写:

signed a;

字符类型中的 signed 和 unsigned

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

C语言规定char类型默认是否带正负号,由当前的系统决定。

也就是说,char类型可能是signed char,也可能是unsigned char。

signed char a;  //取值范围:-128 到 127
unsigned char a;  //取值范围:范围为 0 到 255

数据类型的取值范围

上面介绍了很多数据类型,但不同的数据类型的取值范围是不一样的,我们去使用这些数据类型的时候应该取最合适的数据类型去使用,比如我们需要应该最大数是10,但你使用的数据类型的最⼤值却是10的10倍,所以我们在写代码的时候,应该考虑好使用的范围来确定数据类型的使用。

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

具体可以通过上述两个文件查看。

各种数据类型的⻓度

每一种数据类型都有自己的长度,使用不同的数据结构,可以创建出不同长度的变量,变量长度的不同,存储数据的范围也会有所差异

sizeof操作符

sizeof是一个关键字,也是操作符,专门用来计算sizeof‘操作符数的类型长度单位是字节

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

sizeof (类型)
sizeof 表达式

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

-sizeof后边的表达式是不真实参与运算的,是根据表达式的类型来计算出大小的

-sizeof计算的结果是size_t 类型的

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

在这里插入图片描述
上述我们说sizeof的操作符可以是类型,也可以是变量和表达式,我们通过例子中的代码验证,得出的结果也确实是可以的 , 比如当操作数不是类型 ,是变量时,后边的括号是可以省略的。

sizeof的返回值

sizeof运算符的返回值,C语言只规定是无符号整数,没有规定具体的类型,在不同的系统中是不同的,留给系统去做决定。

不同的系统中,返回值的类型有可能是signed int , 或者是unsigned long ,再或者是unsigned long long 都有可能。

对应的 printf() 占位符分别是 %u 、 %lu 和 %llu。

当然C语言也提供了一个解决方法,创造了一个类型别名:size_t , 用来统一sizeof返回值类型 。对于当前的系统可能是unsigned int 或者是unsigned long long。

各种类型的长度

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

在这里插入图片描述
以上就是本篇中提到的各种数据类型的长度(x86环境下)。

sizeof中表达式不计算

例子:

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

在这里插入图片描述
这里我解释一下,为什么打印出来的是4 和 10。

a是int类型,我们知道int类型是4个字节的大小,b是short类型,2个字节的大小,我们将a+b的值赋给a,也就是让a的值加上b的值,最终打印出14,但打印出来的却是10,也就是说,在第一个printf中,表达式并没有相加。这是因为在sizeof中表达式不计算,我们首先明白,sizeof在代码进行编译的时候,就根据表达式的类型确定了大小,而表达式的执⾏却要在程序运期间才能执⾏,编译期间就语句将sizeof处理掉了,所以在代码运行期间就不会执行表达式了。

解释了我为什么打印10,那为什么打印4呢?

a是int类型 , b是shotr类型,我们把值放在,b变量中,让int b 和 short b加在一起,而b变量是int类型的,所以最终sizeof最终计算的也是int类型的大小 , 我们把 a = a +19 , 换成 b = a + 19 , 最终打印的就是2了,因为short类型的大小就是2。

变量

变量的创建

了解了类型,那么类型是用来干嘛的?类型是用来创建变量的。

什么是变量?C语言中把可以变化的值叫变量,不能变化的值叫常量。

变量创建的语法形式:

	int       a 
//数据类型  //变量名
char a;  //字符变量
int b;   //整型变量
float c; //浮点变量

变量初始化

变量在创建的时候,给一个初始值叫初始化。

int a = 10 //这就是初始化
char b = 10;
float c = 1.1;

变量的分类

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

全局变量:在大括号外部定义的变量,叫全局变量。
全局变量的使用范围更广,在整个工程内都能使用。

局部变量:大括号内部定义的变量,叫局部变量。
局部变量的使用范围比较有限,只有自己局部范围内可以使用。

#include <stdio.h>

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

大括号说的就是main里面和外面。

那当全局变量和局部变量的变量名是一样的,printf()函数会打印全局变量还是局部变量?

#include <stdio.h>

int a = 19;//全局变量
int main()
{
	int a = 20; //局部变量
	printf("%d", a);
	return 0;
}

在这里插入图片描述
当全局变量和局部变量的变量名一样时,局部优先,先打印局部变量。

局部变量分很多种,比如比局部变量更局部的变量。

#include <stdio.h>

int a = 19;//全局变量
int main()
{
	int a = 20; //局部变量
	if (1)
	{
		int a = 21;
		printf("%d", a);
	}
	
	return 0;
}

在这里插入图片描述
既然局部变量优先,那么比局部变量更局部的变量则更优先。

变量在内存中的存储

我们再讲一个关于变量的小知识,我们都知道变量的创建,但这些我们创建好的变量都存储在内存的那个位置呢?

我们在学习C语言的时候一般会关注内存中的三个区域:栈区堆区静态区

-局部变量存放在内存的栈区;

-全局变量存放在内存的静态区;

-堆区则用来动态内存管理。

我们简单了解一下,这里不多叙述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值