c语言基本数据类型所占字节 (c语言整型常量的数据类型)

1. 二进制基础

c语言的数据类型与运算,c语言如何强制转换数据类型

N进制转换十进制

计算机常用进制一般有二进制,八进制,十进制,十六进制,所谓进制,就是“逢N进一”。

二进制,逢二进一,数字中只有 0 和 1

例如数字1010对应十进制:12^3+02^2+121+0*0^0=10

八进制**,逢八进一,数字中**有0,1,2,3,4,5,6,7

例如八数字45转换十进制:48^1+58^0=37

十六进制,逢16进一,数字中有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F

例如十六进制数字45转换十进制:416^1+516^0=69

二进制与八进制互转

二进制转换成八进制的方法是,取三合一法

例如:10101001对应八进制:(010)(101)(001)=251

八进制转为二进制,方法是一分三

例如:345对应二进制:345=(011)(100)(101)

二进制与十六进制互转

二进制转换成十六进制的方法是,取四合一法

例如:10101001对应十六进制:(1010)(1001)=A9

十六进制转为二进制,方法是一分四

例如:1F02对应十六进制:1F02=(0001)(1111)(0000)(0010)

十进制转二进制

用2整除十进制整数,得到一个商和余数;再用2去除商,又会得到一个商和余数,如此重复,直到商为小于1时为止,每一位取余,最后倒叙.

例如:45对应二进制:

45/2=1,22/2=0,11/2=1,5/2=1,2/2=0,1/2=1 最后=101101

比较法:512,256,128,64,32,16,8,4,2,1 这个序是对应的二进制次方

例如:173对应为二进制:

从左至右依次开始,173比128大取1,(173-128)=45,45比64小取0,45比32大取1,(45-32)=13,13比16小取0,比8大取1,(13-8)=5,5比4大取1,(5-4)=1,1比2小取0,1比1取1,最后=10101101

小数部份转换

十进制的小数转换为二进制,主要是小数部分乘以2,取整数部分依次从左往右放在小数点后,直至小数点后为0

小数转二进制

0.125=0.1252=0.25取0,0.252=0.5取0,0.5*2=1取1=最终二进制为0.001

以下是0.3转成二进制的过程,

取8位小数的话0.3 =0.01001100,这是一个无限循环的数

内存中的位,字节,字

计算机中的内存是以位为最小存储单位的。通过对内存进行组织,可以引用特定的位集合。把计算机的内存起始位编号为1,每隔8位编号增1,也就是以字节为单位,每隔一个字节编号向上加一,可以对计算机所有内存进行编号。

2. 数据类型概述

C语言规定,在程序中使用的每一个数据,必须指定其数据类型。

c语言的数据类型与运算,c语言如何强制转换数据类型

不同类型,占用空间不同

c语言的数据类型与运算,c语言如何强制转换数据类型

sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。

sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。

#include<stdio.h>

void main() {
  printf("%d\n",sizeof(char));//1
  printf("%d\n", sizeof(short));//1
  printf("%d\n", sizeof(int));//4
  printf("%d\n", sizeof(unsigned int));//4
  printf("%d\n", sizeof(double));//8
  getchar();
}

#include<stdio.h>
#include<limits.h>//极限头文件

void main() {
  printf("%d,%d\n", INT_MAX,INT_MIN);
  printf("%u,%u", UINT_MAX, 0);
  getchar();
}

c语言的数据类型与运算,c语言如何强制转换数据类型

3. 原码反码补码

原码、反码、补码

原码:

最高位为符号位,其余各位为数值本身的绝对值

反码:

正数:反码与原码相同

负数:符号位为1,其余位对原码取反

补码:

正数:原码、反码、补码相同

负数:最高位为1,其余位为原码取反,再对整个数加1

原码例子:

c语言的数据类型与运算,c语言如何强制转换数据类型

对应十六进制:0000 0000 0000 0001

c语言的数据类型与运算,c语言如何强制转换数据类型

对应十六进制:0000 0000 0000 0010

补码例子:

c语言的数据类型与运算,c语言如何强制转换数据类型

这里会发现-1显示为ffffffff,由于int是32位

我们推理一下

-1的原码

1000 0000 0000 0000 0000 0000 0000 0001

取反

1111 1111 1111 1111 1111 1111 1111 1110

负数+1

1111 1111 1111 1111 1111 1111 1111 1111,这个就是-1的补码

原码

反码

补码

7

0000 0111

0000 0111

0000 0111

-7

1000 0111

1111 1000

1111 1001

从这里能发现,计算是用补码存储的

例子:

从这里能发现,计算是用补码存储的

例子:

#include<stdio.h>

void main() {
  int x = -7;
  printf("%p", &x);
  getchar();
}

c语言的数据类型与运算,c语言如何强制转换数据类型

十六进制:ffff fff9

对应二进制:1111 1111 1111 1111 1111 1111 1111 1001

反码(减一): 1111 1111 1111 1111 1111 1111 1111 1000

原码(取反): 1000 0000 0000 0000 0000 0000 0000 0111

补码可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理 。

#include<stdio.h>

void main() {
  int x = -1;
  printf("%p\n", &x);
  printf("%d,%u", x,x);//d带符十进制,%u无符号
  getchar();
}

c语言的数据类型与运算,c语言如何强制转换数据类型

c语言的数据类型与运算,c语言如何强制转换数据类型

切换无符号

c语言的数据类型与运算,c语言如何强制转换数据类型

4. 整型

整型常量的三种表示形式:

十进制整型常量的表示与数学上的表示相同,十进制整型常量前没有前缀,由0~9的数字组成。

八进制整型常量的表示形式是以数字0开头,即以0作为八进制数的前缀,由0~7的数字组成。

十六进制整型常量的表示形式以0x或0X作为前缀,由数字0~9、字母A~F或a~f组成。

类型

存储空间大小

值范围

char

1 字节

-128 到 127 或 0 到 255

unsigned char

1 字节

0 到 255

signed char

1 字节

-128 到 127

int

2 或 4 字节

-32,768 到 32,767 <br>-2,147,483,648 到 2,147,483,647

unsigned int

2 或 4 字节

0 到 65,535 <br>0 到 4,294,967,295

short

2 字节

-32,768 到 32,767

unsigned short

2 字节

0 到 65,535

long

4 字节

-2,147,483,648 到 2,147,483,647

unsigned long

4 字节

0 到 4,294,967,295

#include<stdio.h>

void main() {
  printf("你的编号:%d\n", 10);//十进制常量10
  printf("一个负数:%d\n", -20);//十进制常量-20
  printf("你的年纪%d\n", 044);//八进制的常量->36
  printf("你有多少钱%d\n", -070);//八进制的常量->-56
  printf("蜀国有%d多兵力\n", 0x7F);//八进制的常量->127
  printf("蜀国有%d多兵力\n", -0x7F);//八进制的常量->-127

  printf("这个长整数:%d\n", 10l);
  printf("这个无符号长整数:%u", 12u);
  
  unsigned int x = -20u;//这个会出错,加u后,不能带负号
  getchar();
}

c语言的数据类型与运算,c语言如何强制转换数据类型

这里对就int对应二进制1010

再看一下-10

c语言的数据类型与运算,c语言如何强制转换数据类型

整形变量

整型变量用于存放整型数据。根据数值的表示范围整型可以为整型(int)、短整型(short)、长整型(long)三种。

这三种整型都默认为有符号型(signed),有符号型即可以是正数、负数和0。也可以根据需要,将整型指定为无符号型(unsigned),此时整型变量只能存放非负数。

short、long、signed、unsigned都是一些类型修饰符,用于补充说明变量的特性

#include<stdio.h>

void main() {
  printf("short:%d,int:%d,long:%d\n", sizeof(short), sizeof(int), sizeof(long));
  printf("ushort:%d,uint:%d,ulong:%d", sizeof(unsigned short), sizeof(unsigned int), sizeof(unsigned long));
  getchar();
}

short 只占两个字节,2^16

long 占4个字节,2^32

int 在32位以下计算机与short一样,32位以上计算机与long等价

#include<stdio.h>

void main() {
  short num = 900000;
  printf("今天生产量:%d", num);//这时会溢出
  getchar();
}

修改成int,就没问题了。

#include<stdio.h>

void main() {
  int num = 900000;
  printf("今天生产量:%d", num);
  getchar();
}

使用无符号

#include<stdio.h>

void main() {
  unsigned short unum = 32769;
  printf("今天生产量:%d", unum);//这时不会出错,因为无符号的正数范围更大
  getchar();
}

#include<stdio.h>
#include<limits.h>

void main() {
  short smax = SHRT_MAX;//short 最大值
  short smin = SHRT_MIN;//short 最小值
  printf("%d,%d\n", smax, smin);

  unsigned short usmax = USHRT_MAX;//unsigned short 最大值
  unsigned short usmin = 0;//unsigned short 最小值
  printf("%d,%d\n", usmax, usmin);

  int imax = INT_MAX;//int 最大值
  int imin = INT_MIN;//int 最小值
  printf("%d,%d\n", imax, imin);

  int lmax = LONG_MAX;//int 最大值
  int lmin = LONG_MIN;//int 最小值
  printf("%d,%d", lmax, lmin);

  getchar();
}

5.浮点型

浮点型常量有两种表示形式:十进制小数形式和指数形式。

类型

存储大小

值范围

精度

float

4 字节

1.2E-38 到 3.4E+38

6 位小数

double

8 字节

2.3E-308 到 1.7E+308

15 位小数

long double

16 字节

3.4E-4932 到 1.1E+4932

19 位小数

float.h 头文件定义了宏,在程序中可以使用这些值和其他有关实数二进制表示的细节。

#include<stdio.h>

void main() {
  printf("工资有:%f元\n", 19800.34);
  printf("还有%f零钱\n", 0.35);
  printf("首富有:%f元\n", 1.58e9);//10^9
  printf("手上没几个子:%f元\n", 1.58e-4);//10^-4
  getchar();
}

实型常量的类型细分:

默认为double型,例如3.14就是double类型,

后面加f或F认为是float型,例如3.14f就是float类型

#include<stdio.h>

void main() {
  printf("%d,%d\n", sizeof(1.0),sizeof(1.0f));
  getchar();
}

浮点型变量:浮点型分为单精度型(float)和双精度型(double)两种。

float和double的区别:

float型数据占用4个字节(32bits)存储单元,提供的有效数字是6~7位;

double型数据占用8个字节(64bits)存储单元,提供的有效数字是15~16位。

#include<stdio.h>

void main() {
  float x = 123.4;
  double y = 123.4;
  printf("%f,%f\n", x, y);
  printf("%d,%d", sizeof(x), sizeof(y));
  getchar();
}

#include<stdio.h>
#include <float.h>

void main() {
  printf("float 存储最大字节数 : %lu \n", sizeof(float));
  printf("float 最小值: %E\n", FLT_MIN);
  printf("float 最大值: %E\n", FLT_MAX);
  printf("精度值: %d\n", FLT_DIG);

  printf("\n");
  printf("double 存储最大字节数 : %lu \n", sizeof(double));
  printf("double 最小值: %E\n", DBL_MIN);
  printf("double 最大值: %E\n", DBL_MAX);
  printf("精度值: %d\n", DBL_DIG);
}

海*公伦**式又译作希*公伦**式、海龙公式、希罗公式、海伦-秦九韶公式。它是利用三角形的三条边的边长直接求三角形面积的公式。表达式为:S=√p(p-a)(p-b)(p-c),它的特点是形式漂亮,便于记忆。

c语言的数据类型与运算,c语言如何强制转换数据类型

#include<stdio.h>
#include<math.h>

void main() {
  float a = 5.0;
  float b = 6.0;
  float c = 7.0;
  float s;
  float p = (a + b + c) / 2;//公式里的p为半周长
  s = sqrt(p * (p - a) * (p - b) * (p - c));
  printf("面积:%f", s);
  getchar();
}

6.字符

字符常量

定义:用单引号括起来的单个普通字符或转义字符.

字符常量的值:该字符的ASCII码值

转义字符:反斜线后面跟一个字符或一个代码值表示

转义序列

含义

\

\ 字符

'

' 字符

"

" 字符

?

? 字符

\a

警报铃声

\b

退格键

\f

换页符

\n

换行符

\r

回车

\t

水平制表符

\v

垂直制表符

C 库函数 int putchar(int char) 把参数 char 指定的字符(一个无符号字符)写入到标准输出 stdout 中。

#include<stdio.h>

void main() {
  putchar('A');
  putchar('\n');
  putchar('B');
  putchar('\n');
  putchar('C');
  getchar();
}

c语言的数据类型与运算,c语言如何强制转换数据类型

#include<stdio.h>

void main() {
  putchar('\x45');//十六进制->十进制,对应69->E
  putchar('\101');//八进制->十进制,对应65->A
  getchar();
}

字符串常量

用双引号括起来的字符序列,每个字符串尾自动加个‘\0’作为字符串结束标志。

c语言的数据类型与运算,c语言如何强制转换数据类型

#include<stdio.h>

void main() {
  printf("hello world\n");
  printf("%d\n", sizeof(""));//空时也占了一个字节
  printf("%d\n", sizeof("1"));
  getchar();
}

字符常量是单引号引起来的一个字符,而字符串常量是双引号引起来的若干字符。

#include<stdio.h>

void main() {
  char c = '1';
  int x = 1;
  printf("%p,%p", &c, &x);//在内存中观察区别
  getchar();
}

char做加法

#include<stdio.h>

void main() {
  char c = 'A';
  printf("%c",c);//打印字符
  c = c + 2;
  printf("%c,%d", c,c);//打印字符与对应数字
  getchar();
}

用char 存字符,这个在C编译器下不会出错,在C++下会出错,实际我们不能这么做。

#include<stdio.h>

void main() {
  char c1 = 'A';
  char c2 = "A";//这里会有问题
  getchar();
}

7.ASCII码

ASCII 定义了 128 个字符。

  • 0-31、127(删除键)是控制字符
  • 空白字符:空格(32)、 制表符、 垂直制表符、 换行、 回车。
  • 可显示字符:a-z、A-Z、0-9、~、!、@、、%、^、&、#、$、*、(、)、-、+、{、}、[、]、'、"、<、>、,、?、/、|、\、_、:、;、.,还有顿号、。

这个代码在vs中编译不过去。

#include<stdio.h>
void main() {
  char c;
  printf("请输入一个字符:\n");
  scanf("%c", &c);
  printf("%c的ASCII为%d", c, c);
  getchar();
}

Severity Code Description Project File Line Suppression State Error C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

我们可以scanf_s来替换,问题是scanf_s 不通用。由于 scanf_s 是VS编译器所提供的,所以在其他平台上并不通用,这就导致用 scanf_s 编写出来的代码不通用。

再就是在程序最上面加上

#define _CRT_SECURE_NO_WARNINGS 1

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void main() {
  char c;
  printf("请输入一个字符:\n");
  scanf("%c", &c);
  printf("%c的ASCII为%d", c, c);//c%字符,%d数字
  getchar();
}

来个大小写转换

#include<stdio.h>
//大写转小写
void main() {
  char c;
  c = getchar();//取得用户输入
  printf("%c,%d\n", c,c);
  c = c + 32;
  printf("%c,%d", c,c);
}

getchar()函数实际上是int getchar(void),所以它返回的是ASCII码,所以只要是ASCII码表里有的字符它都能读取出来。在调用getchar()函数时,编译器会依次读取用户键入缓存区的一个字符。

注意:这里只读取一个字符,如果缓存区有多个字符,那么将会读取上一次被读取字符的下一个字

scanf() 是从标准输入流stdio (标准输入设备,一般指向键盘)中读内容的通用子程序,可以说明的格式读入多个字符,并保存在对应地址的变量中。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void main() {
    int a, b, c;
    printf("用空格分开输入:\n");
    scanf("%d%d%d", &a, &b, &c);
    printf("a=%d,b=%d,c=%d\n", a, b, c);
}