C语言-02基本数据类型

目录

一、常量

(一) 定义

(二) 整型常量(整数)

(三) 实型常量(浮点型)

1、十进制小数形式

2、指数形式(浮点形式)

(四) 字符常量

1、普通字符常量

2、转义字符常量

(五) 字符串常量

(六) 符号常量

(七) 地址常量

二、变量与标识符命名

(一) 变量

(二) 标识符

(三)整型变量的操作

1、取值(读)、赋值(写)

2、输出

(四)auto 自动类型变量

(五)register 寄存器变量

三、基本数据类型

(一)unsigned 和 signed(重要)

1、无符号数 unsigned

2、有符号数 signed 默认一般省略

(二)整型 int

(三) 字符型 char

(四) 单精度、(长)双精度型

四、数据类型的转换

(一)自动类型转换

(二)案例

1、有符号和无符号的转换

2、int和double的转换

3、char和short转换

(三)强制类型转换

五、补充

(一)void 无类型 (重要)

(二)volatile型变量(易失变量)

(三)字符输入输出函数

(四) 整形数据溢出


一、常量

(一) 定义

  • 值不能被改变的量

  • 千万不能反过来说:值不能修改就是常量,后面会提到const修饰的常变量

(二) 整型常量(整数)

  • 在内存中以二进制形式存储

  • 十进制整数后面加L/l 表示long int 型常量,往往用于函数调用

  • 八进制、十进制、十六进制都是整型的输出形式

  • 不同进制仅仅是数据的表现形式,不会修改数据本身

 int num = 100;
 //十进制 输出 %d %u %ld %lu
 printf("十进制:num=%d\n", num); // 100
 //八进制 输出 %o 以0开头
 printf("八进制:num=%#o\n", num); // 0144
 //十六进制 输出 %x 以0x开头
 printf("十六进制:num=%#x\n", num); // 0x64
  • 以八进制、十六进制输出十进制数时,在格式占位符中间添加#,以区分输出的结果进制类型。若不添加输出为100 、144、64,这样不能识别数据的进制类型;添加后输出为100、0144、0x64,这样的形式可以看出进制的区分。

(三) 实型常量(浮点型)

  • 在内存中都是以指数形式存储

  • 形式为数符+数字部分+指数部分

1、十进制小数形式

  • 默认为double类型

  • 实数后面加F/f 表示为单精度浮点数,不可以在整数后面加f

  • 实数后面加L/l 表示为长双精度

  • 小数形式输出默认精确到小数点后6位

2、指数形式(浮点形式)

 // 赋值语句 = 两边的类型 尽量保证一致
 float f = 3.14f; 
 double d = 3.14;

 printf("%f\n", 12345f); // %f 输出 float数据
 printf("d = %lf\n", d); // %lf 输出 double数据

 printf("%f\n", 123.45e2); // e表示科学计数法的小数
 printf("%0.8f\n", 123.45e2); // 0.8为域宽控制,规定小数位数,小数点后八位
 printf("%2.3f", 123.456789); 
 // 对于整数部分,如果整数部分位数小于2位,则在前面补0;如果整数部分大于2位,则整数部分原样输出
 // 规定小数位数保留3位,不足补0,超过就四舍五入

 printf("##############\n"); // ##############
 //%5d 表示占5个终端位宽 右对齐
 printf("##%5d##\n",123); // ##  123##
 //%‐5d 表示占5个终端位宽 左对齐
 printf("##%‐5d##\n",123); // ##123  ##

 //%05d 表示占5个终端位宽 右对齐 不足补0
 printf("##%05d##\n",123); // ##00123##
 //千万不能写 %‐05d
 //printf("##%‐05d##\n",123);
 
 //%5.2f 5表示总位宽为5 .2表示小数位保留2位
 printf("##%5.2f##\n", 3.14159f);

(四) 字符常量

1、普通字符常量

  • 单引号表示的是取字符的ASCII值

  • 占一个字节

  • 字符型在内存中是以ASCII码形式存储的

 // ch 存储的是 ‘a’的ASCII值
 char ch = 'a';
 // 'a' == 97是完全等价
 ch = 97;
 printf("ch = %c\n",ch); // 'a'
 printf("ch = %d\n",ch); // 以%d的格式输出'a'的ASCII值97

 printf("%d\n",sizeof('a')); // 4字节 'a' == 97是一个整型常量,占四个字节
 printf("%d\n",sizeof(char)); // 1 字节
  • 注意:char ch = -10;针对这句代码,将-10赋值给字符常量ch。因为字符常量有符号范围为0~255,无符号范围为-128~127,这样赋值是没有错的,字符常量并不是只能赋值字符
  • 重点在于ch的输出,当以%c格式输出时,会输出乱码。因为字符常量输出时需要对照ASCII表进行查找,但是ASCII表只有0~127的数值范围,所以是不能进行这样输出的

2、转义字符常量

  • 以下四个选项中哪两个选项的结果相同?答:B、C
char ch = '\0';
printf("A:%d\n", '0'); // 48
printf("B:%d\n", '\0'); // 0 全部清空为0
printf("C:%d\n", 0); // 0
printf("D:%d\n", "0"); // 字符‘0’地址
​
​
 \101 // 八进制101转化为十进制ASCII值65,代表字符"A"  
 \1234 // 转义字符只有前三个数字构成 4是单独的字符
 \xAB // 以\x开头的十六进制转义字符
 \x // x后面所有的数字

(五) 字符串常量

  • 双引号取的是字符串的首元素的地址

  • 系统自动加‘\0’作为结束标志

  • %s格式输出字符串,从字符串的首元素逐个字符输出,遇到'\0'结束

  • 字符串常量用字符数组来储存

  • 请描述:'a' 和 "a"的区别?

(六) 符号常量

  • 用#define指令指定用一个符号代表一个常量

  • 如:#define PI 3.1415926(注意末尾没有分号)

  • 使用符号常量可以让常量在使用时含义更清楚,并且在需要改变程序中多处用到了同一个常量的时候,能够做到“一改全改”

(七) 地址常量

  • 每一个常量、变量、数组的地址在程序运行期间是不能够改变的

二、变量与标识符命名

(一) 变量

  • 系统根据变量的类型开辟对应的空间,其值可以被修改

  • 变量名代表的是空间的内容,操作变量就是对空间内容的操作

  • 变量必须先定义后使用

  • 变量名的命名规则应符合标识符命名规则

  • C++中用const来定义常变量,该变量的值不能被改变

(二) 标识符

  • 标识符命名规则:只能由字母、数字、下划线’_’组成,并且只能由字母和下划线开头

  • 不能连续出现两个下划线,下划线不能紧跟大写字母开头

  • 变量名用小写,类名用大4写

  • 同一个作用域范围内定义的标识符不允许重名,不允许是关键字(系统定义有作用的)

(三)整型变量的操作

1、取值(读)、赋值(写)

  • 局部变量不初始化,内容随机

int data = 0,num = 0;
printf("num = %d\n",num); // 读,取值

num = 100; // 写 赋值
printf("num = %d\n",num);

data = num; // num读 data写

2、输出

int num1 = 0;
// %d 有符号int数据输出
printf("num1 = %d\n", num1);

unsigned int num2 = 0;
// %u 无符号int数据输出
printf("num2 = %u\n", num2);

long num3 = 0;
// %ld 有符号long数据输出
printf("num3 = %ld\n", num3);

unsigned long num4 = 0;
// %lu 无符号long数据输出
printf("num4 = %lu\n", num4);

short num5 = 0;
// %hd 有符号short数据 输出
printf("num5 = %hd\n",num5);

unsigned short num6 = 0;
// %hu 无符号short数据 输出
printf("num6 = %hu\n",num6);

(四)auto 自动类型变量

(五)register 寄存器变量

  • register变量必须是一个单个的值,并且其长度应小于或等于整型的长度

  • 局部变量和形参可以作为register变量,全局变量静态变量不行

  • register变量可能不存放在内存中不能用取址符运算符“&”来获取register变量的地址

register int num = 10;
// %p输出地址
printf("%p\n",&num); // 错误 不能对寄存器变量取地址

  • 如果没显示标明 register,就类似int num。如果num被高频繁使用系统会自动将其放入寄存器,直接从寄存器里面读取数据,比从内存读取更快

  • 主动加上register,就是告诉系统register修饰的变量将被频繁使用,对其分配地址时尽量将其分配在寄存器中,以提高访问速度

  • 但是,这个修饰词只是告知cpu尽量将变量分配在寄存器中,不一定真的分配(可能优化处理)

三、基本数据类型

  • 基本数据类型:用于定义变量,规定变量的数据类型,合理的利用空间

  • 定义变量的基本格式:数据类型名 变量名(符合标识符规则)

  • 注意长整型在不同平台占据的字节数

类型类型标识符在32位平台字节数在64位平台字节数
整型[signed] int44
无符号整型unsigned int44
短整型short int22
无符号短整型unsigned short int22
长整型long int48
无符号长整型unsigned long int48
字符型[signed] char11
无符号字符型unsigned char11
单精度型float44
双精度型double88
长双精度型long double88

(一)unsigned 和 signed(重要)

1、无符号数 unsigned

  • 数据没有符号位,自身的所有二进制位都是数据位
  • unsigned char表示范围:0000 0000 ~ 1111 1111

2、有符号数 signed 默认一般省略

  • 二进制最高位为符号位,其他位为数据位
  • 最高位为1表示负数,最高位为0表示正数
  • signed char表示范围:1111 1111 ~ 1000 0000 ~ 0000 0000 ~ 0111 1111

(二)整型 int

  • 整型数据以二进制方式储存,十进制数85的二进制形式1010101

  • 被指定为有符号时,数值以补码形式存放,存储单元最高位用来表示数值符号

  • %u为无符号整型的输出格式

  • 有符号与无符号相加,有符号转换为无符号

 unsigned int a = 2147483647;
 printf("%u\n", a); // 2147483647
 a = -123;
 printf("%d\n", a); // -123
 printf("%u\n", a); // 当作无符号位输出,把符号位1当作数据位1,数值很大

(三) 字符型 char

  • 占用一个字节

  • 在C语言中,字符型数据在内存中以补码形式存放

  • 取值范围:ASCII表

 char ch = 'a'; 
 printf("%c\n", ch);
 printf("%d\n", ch); // %d的格式输出字符的ASCII码

(四) 单精度、(长)双精度型

 float f = 3.14; // 定义了一个单精度浮点型float的变量f,并初始化赋值为3.14
 printf("%f\n", f);
 double PI = 3.1415926; // 3.141593
 printf("%lf\n", PI); // %lf是双精度浮点型的格式占位符
 long double ld = 123.456;
 printf("%lf\n", ld);

四、数据类型的转换

  • 无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据定义的类型

(一)自动类型转换

  • 占用内存字节数少(值域小)的类型,向占用内存字节数多(值域大)的类型转换,以保证精度不降低
  • 数据类型的转换(从低到高):int(char、short) — unsigned int — long — double(float)

(二)案例

1、有符号和无符号的转换

  • 有符号与无符号进行算术操作,有符号会转为无符号

     int data1 = ‐20;
     unsigned int data2 = 10;
     // 有符号data1和无符号data2参加计算的时候,会先将data1转换成无符号(‐20的补码很大的正数)
     // 很大的数 + 10 必然 >0
     if(data1+data2 > 0)
     {
         printf(">0\n");
     }
     else if(data1+data2<0)
     {
         printf("<0\n");
     }

  • 运行结果:>0

2、int和double的转换

 int data1 = 10;
 printf("%d\n",sizeof(data1+3.14)); // 8字节

3、char和short转换

  • 由于char、short自身字节数过小,很容易溢出。所以,只要char、short参加运算,都会将自身转换成int
 char ch = 'a';
 short data = 20;
 printf("%d\n", sizeof(ch + ch)); // 4
 printf("%d\n", sizeof(ch + data)); // 4
 printf("%d\n", sizeof(data + data)); // 4 

(三)强制类型转换

  • 强制类型转换只是临时的转换,当前语句有效,在后面的语句中不会更改x的值
 float f = (float)123.456; // 浮点型常量默认作为double类型数据处理
 printf("%f\n", f);
 int i = (int)f; // 浮点型赋值给整型,小数部分会被丢掉
 printf("%d\n", i); // 有时候即使没有强制类型转换,编译器也会默认进行隐式类型转换

 float x = 3.14f;
 int j = 0;
 //强制 类型转换 只是临时的转换 当前语句有效 在后面的语句中不会更改x的值
 j = (int)x;
 printf("j = %d,x = %f\n", j, x); 
  • 运行结果:j=3,x=3.140000

五、补充

(一)void 无类型 (重要)

  • 不能用void 定义变量
void num; // 错误,系统不能确定给num开辟多大的空间

(二)volatile型变量(易失变量)

  • 表示变量是易失的,易变的

  • 强制访存操作,防止编译器去优化,告诉编译器每次必须去内存中取值,而不是从寄存器或者缓存

  • 避免存放在寄存器里,不能得到及时的更新,误输出。
  • 例如:烟雾传感器数据的保存,若数据10%存放在寄存器里,信息没有得到及时的更新,当数据达到临界值90%时,仍然读取10%,这样是很危险的

(三)字符输入输出函数

  • 只能用于单个字符类型的输入和输出

 char ch;
 ch = getchar(); // getchar用从键盘获取一个字符
 putchar(ch);
 getchar(); // 吸收回车,由于getchar没有获取到字符就不会让程序继续往下执行,所以getchar()可以用来卡一下窗口
 system("pause"); // 暂停窗口
  • 案例:键盘输入 “abc” 只取 'a'和‘c’
char ch1,ch2;
printf("请输入abc:");

ch1 = getchar();
getchar(); // 丢弃一个字符
ch2 = getchar();

printf("ch1 = %c\n", ch1); // ac
printf("ch2 = %c\n", ch2);

(四) 整形数据溢出

  • 当整型数据超出取值范围(计算机字长的界限),数据呈环形变化,也称叫数据出现溢出

  • short为例 二进制十进制
    0111 1111 1111 1111 + 1 = 1000 0000 0000 00001*2^15-1=32767
    1111 1111 1111 1111-1*2^15=-32768
  • 数值范围为-32768~32767

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盾山狂热粉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值