数据类型

引言

程序对数据进行操作,需要了解数据各种类型、特点及如何声明;同时还会理解变量的三者属性:做用域、链接属性和存储类型,这三个属性决定一个变量的“可视性”(在什么地方使用)和“生命期”(值可以保持多久)。

基本数据类型

在C语言中,仅有4种基本数据类型---整数、浮点型、指针和聚合类型(如数组和结构体等),其他的类型都是在4中基本数据类型的某种组合派生而来。

整型家族包括字符、短整型、整型、长整型,且分为有符号(signed)和无符号(unsigned)两种;

规定整型值互相之间大小规则

长整型至少应该和整型一样长,而整型至少和短整型一样长

ANSI标准加入一个规范,说明各种整型值的最小允许范围:

类型最小范围
char0~127
signed char

-127~127

unsigned char0~255
short int -32767~32767
unsigned short int 0~65535
int-32767~32767
unsigned  int0~65535
long int -2146483647~2146483647
unsigned long int 0~4294967295
  

各个变量在内存中所占空间

#include<stdio.h>
int main(){
	char c; 
	int a = 10;
	long b = 20;
	
	char *p;
	int *q;
	
 	printf("sizeof(char):%d\n",sizeof(c));
 	printf("sizeof(int):%d\n",sizeof(a));
 	printf("sizeof(long):%d\n",sizeof(b));
 	printf("sizeof(float):%d\n",sizeof(float));
 	printf("sizeof(double):%d\n",sizeof(double));
	printf("char *p: %d\n",sizeof(p)); 
	printf("int *q : %d\n",sizeof(q)); 

    return 0;
}

64位系统运行结果

sizeof(char):1
sizeof(int):4
sizeof(long):4
sizeof(float):4
sizeof(double):8
char *p: 8
int *q : 8

32位系统运行结果

sizeof(char):1
sizeof(int):4
sizeof(long):4
sizeof(float):4
sizeof(double):8
char *p: 4
int *q : 4

注意指针变量32位系统占4个字节在64位系统8个字节

 

常量与变量

首先看C语言中的关键字
C的关键字共有32个

1)数据类型关键字(12)

char,short,int,long,float,double,unsigned,signed,struct,union,enum,void

2)控制语句关键词(12)

if,else,switch,case,default,for,do,while,break,continue,goto,return,

3)存储类关键词(5)

auto,extern,register,static,const,

4)其他关键词

sizeof,typedef,volatile

数据类型

作用:编译器预算对象(变量)分配的内存空间大小

常量

程序运行中,其值不能被改变,且常量一般出现在表达式或赋值语句中

整型常量

100,200,-100,0

实型常量

3.14 , 0.125,-3.123

字符型常量

‘a’,‘b’,‘1’,‘\n’

字符串常量

“a”,“ab”,“12356”

变量

程序运行中,其值可以被改变,且使用必须先定义;

标识符规则:只能由字母、下划线、数字,不能是关键字;

第一个必须为字母或下划线,且区分大小写

特点:变量在编译时为其分配内存空间,可通过其名字和地址访问相应的内存

声明和定义

声明变量不需要建立存储空间,如extern int a;

定义变量需要建立存储空间,如int b;

#include<stdio.h>
int  main((){
    //extern 关键字只做声明,不能做任何定义
    //声明一个变量a,a在这里没有建立储存空间
    extern int a;
    a =10;//erro,没有空间,不能赋值
    int b=10; //定义一个变量b,b的类型为int,b赋值为10
    return 0;
}

区分声明和定义定义是声明的一个特例,一般将建立储存空间的声明称为定义不需要建立存储空间称为声明。

示例

#include<stdio.h>
#define MAC 10 //声明一个常量,名为MAC 值为10,常量的值一旦初始化不可改
int main()
{
    int a;//定义一个变量
    
    const int b =10;//定义一个const 常量,名为b,值为10
    b=11;//erro,常量的值不能改变
    MAC =10;//erro:常量的值不能改变
    a = MAC;
    a =12;
    printf("%d\n",a);

}

进制

进制即进位制,一种人为规定的进位方法,对于X进制表示:数运算时逢X进一位。十进制时逢十进一,二进制、十六进制类似

十进制

二进制(0b)

八进制(0)

十六进制(0x)

0

0

0

0

1

1

1

1

2

10

2

2

3

11

3

3

4

100

4

4

5

101

5

5

6

110

6

6

7

111

7

7

8

1000

10

8

9

1001

11

9

10

1010

12

A

11

1011

13

B

12

1100

14

C

13

1101

15

D

14

1110

16

E

15

1111

17

F

16

10000

20

10

二进制

二进制时计算机系统中采用的一种数制。二进制数据时用0和1两个数码表示数。基数为2,逢二进一,借位规制时借一当二

数据在计算机中主要以补码的形式存储。

术语

含义

bit(比特)

一个二进制代表一位,一个位只能表示0或1两种状态。数据传输是习惯以“位”(bit)为单位。

Byte(字节)

一个字节为8个二进制,称为8位,计算机中存储的最小单位是字节。数据存储是习惯以“字节”(Byte)为单位。

WORD(双字节)

2个字节,16位

DWORD

两个WORD,4个字节,32位

1b

1bit,1位

1B

1Byte,1字节,8位

1k,1K

1024

1M(1兆)

1024k, 1024*1024

1G

1024M

1T

1024G

1Kb(千位)

1024bit,1024位

1KB(千字节)

1024Byte,1024字节

1Mb(兆位)

1024Kb = 1024 * 1024bit

1MB(兆字节)

1024KB = 1024 * 1024Byte

十进制转二进制方法:用十进制数除以2,分别取余数和商数,商数为0时,将余数倒着数即为结果

十进制的小数部分转换为二进制:小数部分和2想乘,取整数,不足1取0,每次相乘时小数部分,顺序看取整后的数就是转化后的结果

八进制

八进制,Octal,缩写OCT或0,一种以8为基数的计数法,采用0,1,2,3,4,5,6,7八数字,逢八进一。编程中以数字0开始表明为八进制;

八进制一位对应二进制三位

十进制转化为八进制方法

十进制数除以8,分别取余数和商数,商数为0的时候,将余数倒着的数即为结果。

十六进制

英文:Hexadecimal,它有0-9,A-F组成,字母不区分大小写。与10进制的对应关系:0-9对应0-9,A-F对应10-15;

十六进制数一位对应二进制的四位数。

十进制转十六进制:

用十进制数除以16,分别取余数和商数,商数为0的时候,将余数倒着数即结果。

接下来看下C语言中如何表示各个进制数

十进制

以正常数字1-9开头,如123

八进制

以数字0开头,如0123

十六进制

以0x开头,如0x123

二进制

以0b开头,C语言不能直接书写二进制数,如0b00111100....

#include<stdio.h>
int main()
{
    int a=12;   //十进制赋值
    int b = 021; // 八进制赋值,以数字0开始
    int c = 0xAB;  //十六进制赋值
    
    //在printf()中输出一个十进制数那么用%d,八进制用%o,十六进制用%x
    printf("十进制: %d\n",a);
    printf("八进制: %o\n",b);
    printf("十六进制: %x\n",c);
    return 0;

}

结果

十进制: 12
八进制: 21
十六进制: ab

计算机内存数值存储方式

原码

一个数的原码原始的二进制码):最高位作为符号位,0表示正,1表示负;其他数值部分就是数值本身绝对值的二进制;

负数的原码是在其绝对值的基础上,最高位变为1。

十进制数

原码

+15

0000 1111

-15

1000 1111

+0

0000 0000

-0

1000 0000

原码表示法简单易懂,与带符号数本身转换方便,只要符号还原即可,但当两个正数相减或者不同符号数相加时,必须比较两个数那个绝对值大,这决定谁减谁,确定结果是正是负,故原码不便于加减运算;

反码

对于正数,反码与原码相同

对于负数,符号位不变,其他部分取反(1变0,0变1)。

十进制数

反码

+15

0000 1111

-15

1111 0000

+0

0000 0000

-0

1111 1111

补码

在计算机系统中,数值一律用补码来存储

  • 对于正数原码、反码、补码相同;
  • 对于负数,其补码为它的反码加1;

补码符号位不动其他位求反,最后整个数加1,得到原码

十进制数

补码

+15

0000 1111

-15

1111 0001

+0

0000 0000

-0

0000 0000

#include<stdio.h>

int main(){
    int a =-14;
    printf("%x\n",a); //打印十六进制数
    printf("%o\n",a);//打印八进制数
    printf("%d\n",a);
    //结果为fffffff2
    //fffffff1对应的二进制:  1111 1111 1111 1111 1111 1111 1111 0001
    //符号位不变,其他取反:   1000 0000 0000 0000 0000 0000 0000 1110
    //上面加1最高位1代表负数: 1000 0000 0000 0000 0000 0000 0000 1111
    return 0;

}

补码的意义

例1:用8位二进制数分别表示+0和-0

十进制数

原码

+0

0000 0000

-0

1000 0000

十进制数

反码

+0

0000 0000

-0

1111 1111

0以原码或反码方式存储,存在两种表现形式,补码统一了0的编码:

十进制数

补码

+0

 0000 0000

-0

10000 0000由于只用8位描述,最高位1丢弃,变为0000 0000

例2补码方式相加:

十进制数

补码

9

0000 1001

-6

1111 1010

最高位的1溢出,剩余8位二进制表示的是3,正确。

在计算机系统中,数值一律用补码来存储,主要原因是:

  1. 统一了零的编码
  2. 将符号位和其它位统一处理
  3. 将减法运算转变为加法运算
  4. 两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃

sizeof关键

  1. sizeof不是函数,所以不需要包含任何头文件,它的功能是计算一个数据类型的大小,单位为字节
  2. sizeof的返回值为size_t;

size_t类型在32位操作系统下是unsigned int,是一个无符号的整数字

#include<stdio.h>
int main()
{
	int a;
	int b = sizeof(a);//sizeof得到指定值占用内存的大小,单位:字节
	printf("b = %d\n", b);

	size_t c = sizeof(a);
	printf("c = %u\n", c);//用无符号数的方式输出c的值

	return 0;
}

练习

十进制111书分别用二进制、十六进制表示;此数如果为一个unsigned int类型,在32bit宽little-endian模式CPU中按byte的存放方式为

111二进制为0b01101111;(高位0省略)

111十六进制为0x006f;(高位0省略)

一个unsigned int类型占4个字节即32bit,

二进制方式在32bit宽little-endian模式CPU中按byte的存放方式为:...,0000 0000,01101111(假设地址从高到底)

二进制方式在32bit宽little-endian模式CPU中按byte的存放方式为:00,6f           (假设地址从高到底)

CPU存储方式—Big Endian、Little Endian

为什么会有Little-Endian和Big-Endian之分?

  在计算机系统中,是以字节为单位的每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节存储的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式就将0x11放在低地址中,即0x0010中0x22放在高地址中,即0x0011中小端模式,刚好相反。常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式,有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值