2.基本数据类型和变量

1.数据类型

这次主要了解基本数据类型和布尔类型
在这里插入图片描述

注:[ ]表示可以省略不写
1.1 字符
char
[signed] char
unsigned char

1.2 整型
短整型
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]

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

1.4.布尔类型(C99开始引入)
1.布尔类型用 _Bool 表示
2.布尔类型的使用需要引用头文件<stdbool.h>
3.布尔类型变量取值有true或false

//布尔类型
#include <stdio.h>
#include <stdbool.h>
int main() {
    
    
	_Bool flag = true;
	if (flag) {
    
    
		printf("i'm true");
	}
	else{
    
    
		printf("i'm false");
	}
	return 0;
}

在这里插入图片描述

2.signed和unsigned

C语⾔使⽤ signed 和 unsigned 关键字修饰字符型和整型类型的。
signed 关键字,表示⼀个类型带有正负号,包含负值;
unsigned 关键字,表示该类型不带有正负号,只能表示零和正整数(非负)。

所以上面介绍数据类型的时候,如果要求数据类型只表示非负整数,那就必须使用unsigned关键字来修饰;除此之外都可以用signed关键字来修饰,但是大都数据类型范围本身就包含正负,所以基本可以省略signed。

例:

//定义整型变量a
signed int a;
int a;//signed可以省略

//定义非负整型变量a
unsigned int a;

以整型int为例,int变量声明unsigned有什么好处呢?
好处就是同样的内存长度能够表示的最大整数值大了一倍。
比如:
16位的 signed short int 的取值范围是:-32768~32767,最大是32767
而unsigned short int 的取值范围是:0~65535,最大值到了65535

3.数据类型的取值范围

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 的最大值。

代码演示

#include <limits.h>
int main() {
    
    
//存储大小
	printf("char的存储大小:%d\n",sizeof(char));
	printf("short的存储大小:%d\n", sizeof(short));
	printf("int的存储大小:%d\n", sizeof(int));
	printf("long的存储大小:%d\n", sizeof(long));

	//short int和long int 就是 short和long 这定义类型可以省略int 
	printf("short int的存储大小:%d\n", sizeof(short int));
	printf("long int的存储大小:%d\n", sizeof(long int));

	printf("long long的存储大小:%d\n", sizeof(long long));
	printf("unsigned char的存储大小:%d\n",sizeof(unsigned char));
	printf("unsigned short的存储大小:%d\n",sizeof(unsigned short));
	printf("unsigned int的存储大小:%d\n",sizeof(unsigned int));
	printf("unsigned long的存储大小:%d\n",sizeof(unsigned long));
	printf("unsigned long long的存储大小:%d\n",sizeof(unsigned long long));

	printf("float的存储大小:%d\n", sizeof(float));
	printf("double的存储大小:%d\n", sizeof(double));
	printf("long double的存储大小:%d\n", sizeof(long double));//long double字节大小至少8字节,不同编译器得出的结果不同,但肯定大于等于double的8字节

	printf("--------------------------------------------\n");
	
//取值范围
	printf("char的取值范围:%d %d\n", SCHAR_MIN, SCHAR_MAX);
	printf("unsigned char的取值范围:%d\n", UCHAR_MAX);	

	printf("short的取值范围:%d %d\n", SHRT_MIN, SHRT_MAX);
	printf("unsigned short的取值范围:%d\n", USHRT_MAX);

	//%d 十进制有符号整数   
	printf("int的取值范围:%d %d\n", INT_MIN, INT_MAX);
	//%u (16位)十进制无符号整数(unsigned int的最大存储范围已经超出了%d所能表示的范围)
	printf("unsigned int的取值范围:%u\n", UINT_MAX);

	//%d=int  %ld=long  %lld=long long(long和long long的取值范围都已经超出了int的范围 所以对应的格式化占位符也要修改 否则会出错

	//%ld [32位]长整型数据类型
	printf("long的取值范围:%ld %ld\n", LONG_MIN, LONG_MAX);
	//%lu [32位]无符号长整型数据类型
	printf("unsigned long的取值范围:%lu\n", ULONG_MAX);

	//%lld 64位长整型数据类型
	printf("long long的取值范围:%lld %lld\n", LLONG_MIN, LLONG_MAX);
	//%llu 64位无符号长整型数据类型
	printf("unsigned long long的取值范围:%llu\n", ULLONG_MAX);

	return 0;
}

在这里插入图片描述

4.变量

变量就是C语言中可以变化的值,创建变量时要给变量定义数据类型。

常量就是C语言中不变化的值,比如上面数据类型中提到的整数类型的取值范围
INT_MIN,INT_MAX就表示int类型的最小和最大取值范围,这两者就是一种常量。

定义变量
定义变量很简单,数据类型+变量名(变量名不要和关键字冲突)

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

初始化变量
在变量创建时就给其一个初始值
初始值要对应数据类型

int a = 1;
char b = '1'
float c = 1.1;

不初始化变量
整型变量(int、short、long等):默认值为0。
浮点型变量(float、double等):默认值为0.0。
字符型变量(char):默认值为’\0’,即空字符。

5.全局变量和局部变量

全局变量: 在大括号外部定义的变量为全局变量
全局变量影响的范围广,涉及整个项目,随处都可以引用

局部变量: 在大括号内部定义的变量为局部变量
局部变量只能影响局部范围,一般在自己的大括号内可以引用

#include <stdbool.h>
//全局变量和局部变量
int global = 1;//全局变量
int main() {
    
    
	int local = 2;//局部变量
	if (true){
    
    
		int local_in = 3;//局部变量
		printf("局部变量:%d\n", local_in)//这里就可以调用local_in局部变量
	}

	printf("全局变量:%d\n", global);
	printf("局部变量:%d\n", local);
	//printf("局部变量:%d\n", local_in); //无法调用局部变量local_in,报错
}

若调用的局部变量 在相对于调用点更内部的大括号内定义的话,则无法调用局部变量
以上述int local_in = 3为例,外部打印调用local_in时,无法找到比自身更内部的local_in的定义,所以调用失败,报错。

若局部变量和全局变量 变量名相同

#include <stdbool.h>
//全局变量和局部变量
int global = 1;//全局变量
int main() {
    
    
	int global = 2;//局部变量
	printf("全局变量:%d\n", global);
}

调式结果
在这里插入图片描述
原因:内部的局部变量覆盖了全局变量的值。(这里的覆盖不是指修改全局变量的int global = 1,而是将打印这一步骤中的global值覆盖,原先定义的值都不变)

局部变量和全局变量在内存中存储的位置(了解)
1.局部变量存储在内存的栈区
2.全局变量存储在内存的静态区

6.算术运算符(+、-、*、/、%)

**+   -   *   /   % **这几个算术运算符都是双目运算符。
注:双目运算符就是指运算符有两个操作数,也就是运算符两端各有一个数。

//算数运算符
int main() {
    
    
	//加 减 乘(+ - *)
	int a = 1, b = 2, c = 3;
	int add = a + b + c;
	int sub = c - b - a;
	int mul = a * b * c;
	printf("add=%d  sub=%d  mul=%d\n", add, sub, mul);

	return 0;
}

在这里插入图片描述



加减乘都很有规律,这里把除法单独拎出来讨论一下!!!

int main() {
    
    
	// 除(/)
	int a = 1, b = 2, c = 3;
	float bf = 2, cf = 3;

	int div_i = c / b;
	float div_f1 = c / b;
	float div_f2= cf / bf;

	printf("div_i=%d\n", div_i);//1
	printf("div_f1=%f\n", div_f1);//1.000000
	printf("div_f2=%f\n", div_f2);//1.500000

	return 0;
}

在这里插入图片描述
出现三种不同的结果,逐个讨论
提示:C语言中整数除法都是整除,它只会返回整数部分,丢弃小数部分。

1、 printf(“div_i=%d\n”, div_i);//1
式子 int div_i = c / b 结果变量div_i类型为int,且运算符的两端的操作数c、b都是int类型
按流程来:
两个int变量c和b相除,结果为1,赋值给变量div_i
又因为div_i是int类型,所以div_i=1
然后用占位符%d 输出打印

2、printf(“div_f1=%f\n”, div_f1);//1.000000
式子 float div_f1 = c / b 结果变量div_f1类型为float,且运算符的两端的操作数c、b都是int类型
按流程来:
两个int变量c和b相除,结果为1,赋值给变量div_f1
又因为div_f1是float类型,所以div_f1=1.000000
然后用占位符%f 输出打印

3、printf(“div_f2=%f\n”, div_f2);//1.500000
式子 float div_f1 = cf / bf 结果变量div_f2类型为float,且运算符的两端的操作数c、b都是float类型
注:这里的变量是float类型相除(只要其中至少有一个float变量参与运算,C语言就会进行浮点数除法),算浮点数相除,除法就不会为整除
按流程来:
两个float变量c和b相除,结果为1.500000,赋值给变量div_f2
因为div_f2是float类型,所以div_f2=1.500000
然后用占位符%f 输出打印



运算符%表示取模运算,即返回两个整数相除的余数。
(这个运算符只能运用于整数,不能用于浮点数)

//取模%
int main() {
    
    
	int b = 2, c = 3;
	int mod = c % b;
	printf("mod=%d", mod);//1
	return 0;
}

负数求模的规则是,结果的正负号由第一个运算数的正负号决定。

int main() {
    
    
	printf("%d\n", 11 % -5); // 1
	printf("%d\n", -11 % -5); // -1
	printf("%d\n", -11 % 5); // -1
	return 0;
}

7.赋值运算符(=)

变量创建的时候给一个初始值加初始化,变量创建完之后再给一个值叫做赋值。

//赋值运算符
int main() {
    
    
	int a = 100;//初始化
	a = 101;//赋值
	return 0;
}



连续赋值

//连续赋值
int main() {
    
    
	int a = 100;//初始化
	int b = 101;//初始化
	int c = 102;//初始化
	a = b = c + 98;//不推荐变量连接成一块,看着费劲
	
	//建议分开写,方便观察读写
	b = c + 98;
	a = b;
	printf("a=%d b=%d c=%d",a,b,c);//从右向左依次赋值的 200 200 102
	
	return 0;
}

从右向左依次赋值的

在这里插入图片描述


复合赋值符

//复合赋值
int main() {
    
    
	int a = 100;
	int b = 100;
	a += 3;//等同于 a = a + 3
	b -= 3;//等同于 b = b - 3

	printf("a=%d\n", a);//103
	printf("b=%d\n", b);//97

	return 0;
}

常用的复合赋值符

*= /= %= /= %=
>>= <<= &= |= ^=

8.单目运算符(++、–、+(正)、-(负))

++、- -、+(正)、-(负)这几个运算符都只有一个操作数,所以是单目运算符

+(正) -(负)
正负号就不多介绍了,就是数学中的正负
正号(+)基本可以省略,写不写都可以
负号(-)就是让数变成负数呗,也是很简单的道理,不过多介绍

++和- -
++自增,- -自减,++的作用就是将变量+1,- -的作用就是使变量-1
++和- -可以前置或者后置于操作数,前置和后置会导致+1的先后顺序不同

int main() {
    
    
	int a = 1;
	int b = a++;
	printf("b=%d\n", b);//b=1
	printf("a=%d", a);//a=2
	return 0;
}

上述例子为自增后置
int b = a++ 先将a=1赋值给b,所以b=1
再 自增a++(等同于a = a+1) 所以a=2


int main() {
    
    
	int a = 1;
	int b = ++a;
	printf("b=%d\n", b);//b=2
	printf("a=%d", a);//a=2
	return 0;
}

上述例子为自增前置
int b = ++a 先自增a++(等同于a = a+1),所以a=2
再 将a=2赋值给b,所以b=2

同理可得自减的前置和后置,就不举例了^ _ ^

9.强制类型转换

int main() {
    
    
	int a = 3.14;
	printf("a=%d", a);
	return 0;
}

在这里插入图片描述
会弹出警告,有的编译器会直接报错,浮点数转整型会牺牲精度,丢失小数部分的数据


为了消除警告,需要使用强制类型转换,在需要转换的值或类型前加上(类型)

//强制类型转换
int main() {
    
    
	int a = (int)3.14;//浮点数前加上  (强制转换的类型)
	printf("a=%d", a);
	return 0;
}

成功运行不报错没警告,但是仍然丢失精度

猜你喜欢

转载自blog.csdn.net/qq_45657848/article/details/131846662