数据类型 运算符 表达式

介绍数据类型

我们略过基础性的问题,直接点电干货

思考基本数据类型
1)所占字节数(怎么算的):根据硬件平台
2)储存区别
3)不同类型的数据之间如何进行转换(这个一定要非常熟练)
4)特殊性

先看整形数据计算机是如何存储的;

我们都知道计算机只识别二进制,但是我们并不能用二进制去写程序,所以这就涉及我们用其他进制去写程序,那计算机是如何转换成二进制的呢?首先计算机的整形数据其实是以补码的形式进行存储,补码用来区分正数和负数
在这里插入图片描述

求补码方式:
正数:本身,
负数:去绝对值取反+1
1 为什么不能把-1表示成1000 0001???
因为涉及二进制加减法问题
2 正数最大是0(符号位)111 1111 负数最小1(符号位)111 1111 的问题?
负数最小的源码是1111 1111
举例 unsigned int = 254 用8421法求进制转换 (254)10 = (… 1111 1110)

整形和其他类型的转换:这个比较简单就用8421法求进制转换

有符号和无符号区别:
1计算机就需要根据定义的类型来判断最高位是符号位还是有效计算数值位
2同一个类型表示的数据个数一样,但是数据范围有区别

实型的数据是如何存储的

先看一个列子 比如3.14还可以用其他方式来表示:
3.14×1:其实就是3.14×10^0
0.314 ×10::其实就是0314×10^1
0.0314×10^2
314×10^-2
那他是如何在内存中存储的呢
实型数据细分三部分组成 存储,也可以说主要是两部分组成存储,从低位到高位,以32位为例
{符号位()+指数位()}+精度位()
在这里插入图片描述
终极明白一图搞定
在这里插入图片描述

而浮点型 用的都是这种0.314 ×10::其实就是0314×10^1形式来存储
如0.000314 ->0.314×10^-3

字符型的数据是如何存储的

这里设计ASCLL码(0-255共256个 前128个事标准c语言规定的)
也是以补码形式存储

我们要记住常用的 ‘a’----97 ‘0’—48 ‘A’----65
注意字符型也分有无符号之分 但是标准C未定义,你定义了什么类型他就是什么类型

不同类型数据和相同数据之间相互的转换

注意不同类型之间转换会存在精度丢失的情况
方法
1:隐式->不同类型之间的运算会自动想字节数高的类型转换,也就精度高的类型
2:显式->强制转换
类型的

特殊性

1 布尔型bool:其实就是两个逻辑值0和1

下面展示一些 内联代码片

// An highlighted block
include<stdio.h>
inlcude<stdbool.h>		//布尔类型头文件
int main()
{
	bool a = false;//布尔类型定义
	printf("a = %d\n",a);//打印输出假值0
	
}

2 float类型
1,我们知道二进制只有0和1,那你知道计算机是怎么知道1.5在哪个位置吗
其实float并不是一个非常精确的数值,
在这里插入图片描述

那计算机怎么确定一个浮点型是接近0大于0的呢
用/f - 0/的差如果精度在一个范围如0.000001(用10^-6)以内,就可说约等于0
所以(float类型==0)是没有这种写法的

2,怎么用
float类型==0)可以写成
fabs(f-0) <= 1e-6 就可以说约等于0

3 char型是否有符号

4 不同形式的0值
0 ‘0’ “0”“\0” NULL

5数据类型要与后续代码中所使用的输入输出要相匹配
比如相同类型有无符号之间的转换
因为有无符号所表示的数值取值范围不同
定义signed char a (-127 --127)
printf(%d\n,a)//%d是默认有符号的十进制,
假如a =200 那输出的超过了signed 最大的范围,所以肯定输出的是负值,出现精度丢失

介绍数据类型应用在哪些地方

变量和常量

一定要区分这些小的概念,概念是对某一个问题理解是否正确的出发点,一定要从概念中去理解这些细节

常量:数值不会变
变量:程序执行中可变

常量
用到多的有关常量的类型
一:字符和字符串常量
这里有一些判断是字符还是字符串的易错情况
注意区别‘a’和“a”
‘a’:字符常量
‘“a”:字符串常量

二:标识符常量
define
总结define的特点和用法这个非常重要
为什么要用?

// An highlighted block
int main()
{
	3.24259//会经常用到的这个常量,但是我想一改全改
}

如何用
#define pi 3.14159
详细的说下什么意思,,#不用说了预处理要解决的事情,pi叫宏名 ,3.14159叫宏体,在编辑时都用宏名表示,但是说在预处理的时候,宏名就被宏体全部代替这是优点,
预处理过程可显示出来用:gcc -E 源文件.c 可查看预处理是什么效果
用法:
1 带()的使用
同时缺点是不检查语法,因为我们知道宏定义的特点就是单纯的****完整替换,但不能检查出这个宏体是不是我们想要的数值类型,例:
宏体 3+2 和(3+2)对于替换 pi * pi的运算结果是不同的,**因为你输入什么样的他替换就是什么样的!**一定记住这句话
2带参数的宏的使用
三目运算 a?b:c
这里再运用的时候会有一些复杂的情况,因此严格的写应该是(a?)(b):(c)
比如参数自增 ,参数有运算

// 比如要比较3,和4的大小
define MAX(a,b)   (a)>(b)?(a):(b)
代码
printf("%d\n",max(i++,m++))

预处理后是(i++)>(m++)?(i++):(m++)

这里的i在运算后自增了两次,我原本想比较是3和4的大小,输出最大值是4,,,结果是比较4和5的大小,最后输出的最大值是6.与我们初衷的想法不一致。那则么解决呢:
1用一个变量来接受#define MAX(a,b) ({int A=a,B=b;(A)>(B)?(A):(B);})用变量去比较就行了,两个分号相当于两条语句,
在这里插入图片描述
在这里插入图片描述
2 深入改一下
AB不一定是整形:用typeof 来获取MAX(a,b)中a的类型
在这里插入图片描述
最后结果一样!!

这里我们还得知道宏作为运算功能的时候用法和函数的区别

首先define占用的是预处理时间就是编译时间后面不会再占用运行时间了,而函数是再调用的位置先做一个压栈保存,然后跳往函数入口地址进行运行,然后再回到被调用地方的这样一个过程,占用了更多运行时间

那怎么区分什么情况下用宏定义和函数呢
(内核中):首先要明白宏定义完成一个功能相对于函数来说是比较危险的,但是比较节省运行时间,要求更高效率的时候
(应用层):要求更稳定的时候用函数

3对于赋值的使用
不可能出现在左值 define a 5 那程序中就不能在出现a = 常量;

变量

定义使用

【存储类型】数据类型 + 标识符(字母数字_) = 值(注意类型匹配)
标识符(变量):
1一块内存空间的名字
2见名知义
数据类型:基本类型+构造类型

存储类型:定义型(auto static register) extern(说明型) 这里有个问题存储类型的比较??要详细了解
auto:默认 ,空间自动分配自动回收

register:(建议型)寄存器(存在cpu)类型
这个用法有点复杂;要满足把所定义的变量放到寄存器类型中要满足苛刻的条件:1只能用来定义局部变量2大小有限制(32位平台只能定义32位,如double就不行)3寄存器中无地址,所以一个寄存器类型的变量无法打印出地址查看或使用

static:静态型,自动初始化0值或空值并且这种变量的值有继承性,(重点常用于修饰变量或者函数(用于全局变量只在当前文件中或者函数中使用))

extern:说明型 ,不能改变被说明变量的值和类型(这个变量实在别的地方已经定义好了 )
简单了解下进程内存分配
在这里插入图片描述
Static与Const的区别

static
static局部变量 将一个变量声明为函数的局部变量,那么这个局部变量在函数执行完成之后不会被释放,而是继续保留在内存中
static 全局变量 表示一个变量在当前文件的全局内可访问
static 函数 表示一个函数只能在当前文件中被访问
static 类成员变量 表示这个成员为全类所共有
static 类成员函数 表示这个函数为全类所共有,而且只能访问静态成员变量

const
const 常量:定义时就初始化,以后不能更改。
const 形参:func(const int a){};该形参在函数里不能改变
const修饰类成员函数:该函数对成员变量只能进行只读操作

static关键字的作用:
(1)函数体内static变量的作用范围为该函数体,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
(2)在模块内的static全局变量和函数可以被模块内的函数访问,但不能被模块外其它函数访问;
(3)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
(4)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

const关键字的作用:
(1)阻止一个变量被改变
(2)声明常量指针和指针常量
(3)const修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为”左值”。

onst就是只读的意思,只在声明bai中使用;
static一般有2个作du用,规定作用域和zhi存储方式.对于局部变量,static规定其为静dao态存储方式,每次调用的初始值为上一次调用的值,调用结束后存储空间不释放;
对于全局变量,如果以文件划分作用域的话,此变量只在当前文件可见;对于static函数也是在当前模块内函数可见.

变量的生命周期和作用范围

提出问题:全局和局部的区别 局部和局部的区别 全局变量的缺陷
全局变量:函数内部 作用范围从定义开始
局部变量:函数外部 作用范围从定义开始
他们的作用范围一定是内部屏蔽外部

表达式和运算符

1他们的概念:

表达式与语句的区别:表达式-》不加分号 加分号就是语句以分号结尾的就是一条完整的语句
运算符就是重点了 :要明白几个内容问题

1 每个运算符所需要的参与运算的操作数个数(单双三目)
2 结核性(左右)
3 优先级
4 特殊符号(运算符的特殊使用)
5 位运算的重要意义

问题一:区别/ 和% 参与运算的区别
问题二: 自增自减使用时应注意的用法
运算符在前:先运算再取值使用(使用的是变量)
变量在前:先使用变量,后运算变量的值
interesting i=1
i++:表达式的值1 i为2
++i:表达式的值2 i为2
问题三:自增自减在连续使用的会因为编辑器不同运算出不同结果 这是因为在扫描表达式时会出现不同的结合性扫描?要知道大概原因
问题四;特殊运算符
%
=与==
逻辑运算符的短路特性:比如逻辑与 左为假 后面不用算了一假全假 逻辑或 左为真 后面也不用算了 符合一真即可
问题五:位运算的重要性!!!
应用:
1 指定某n位 置一其他不变 一定是按位或 num = num | 1<<n
置零:num = num&~(1<<n)
2 测试第n位:if(num&1<<n)
3 从一个指定宽度的数中取出其中的某几位????
例例如 求10(1010)的第三位数
int a=10;
int b=a;
b=b>>(3-1)&1;
得到的b就是10的第三位

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值