C - Languege | Date


数据类型

数据类型是指一定的数据在计算机内部的表示方式

C语言中的数据类型分为" 基本类型 "、" 构造类型 "、" 指针类型 "、" 空类型 "等四大类

//字符用单引号" ' "包裹,字符串用双引号" " "包裹

基本类型
	整类型
        有符号基本整型(int[4])
        无符号基本整型(unsigned[4])
        有符号短整类型(short[2])
        无符号短整类型(unsigned short[2])
        有符号长整类型(long[4])
        无符号长整类型(unsigned long[4])
    浮点类型(实数型)
        单精度浮点型(float[4])
        双精度浮点型(double[8])
        长双精度浮点型(long double[8])
    字符类型
        有符号字符类型(char[1])
        无符号字符型(unsigned char[1])
构造类型
	数组类型
	结构体类型
	共用体类型
	枚举类型
指针类型
空类型
	空类型(void)
数组
	一维数组
		下标变量
	二维数组
		双下标变量
	多维数组
	字符串
	

基本类型

C语言的基本类型包括" 整型 "、" 浮点型(实行) "、" 字符型 "三种

整型

  • 有符号基本整型(int)
  • 无符号基本整型(unsigned int)
  • 有符号短整型(short)
  • 无符号短整型(unsigned short)
  • 有长整型(long)
  • 无符号长整型(unsigned long)

浮点型(实型)

  • 单精度浮点型(float)
  • 双精度浮点型(double)
  • 长双精度浮点度(long double)

字符型

  • 有符号字符型(char)
  • 无符号字符型(unsigned char)

构造类型

构造类型是在基本类型基础上,为了满足问题需要,进行添加、设计构造出的新数据类型

构造类型是多种类型组合而成的新类型,其中每个组成部分成为构造类型的成员

构造类型包括" 数组类型 "、" 结构体类型 "、" 共用体类型 "、" 枚举类型 "四种

数组类型

  • 数组型()

结构体类型

  • 结构体类型(struct)

共用体类型

  • 共用体型(union)

枚举类型

  • 枚举类型(enum)

指针类型

指针的值表示的是某个目标的内存地址

空类型

空类型的关键字是" void ",没有返回值的数据类型,当函数没有返回值时,可以使用空类型设定返回值类型

空类型又称" 空指针" 、" 空类型指针" 、" 无类型指针 "

  • 空类型(void)

常量

常量是指程序运行中,其值不能被改变的量(常量的值固定不变,不会被程序修改)

常量有单独的存储区域(内存空间)

常量分为" 整型常量 "、" 浮点型常量 "、" 字符型常量 "、" 符号常量 "4种

  • 整型常量
  • 浮点型常量
  • 字符型常量
  • 符号常量

初始化常量

初始化常量的格式内容包括:常量标识符(常量名)、初始值、定界符、修饰符

aChar='1';					/*初始常量" aChar "的值为" 1 ",使用字符类型单引号定界符把值进行包裹*/
bNum=01357ul;					/*初始常量" bNum "的为八进制的" 1357 ",使用修饰符" ul "表示" bNum "是长无符号整型*/

整型常量

整型常量是能直接使用的整型常数(整型常数)

整型常量可以是长整型、短整型、符号整形或无符号整型

声明整型常量时,可以在常量名称后面加上"L(长整型) "、" U(无符号整型) "或" LU(无符号长整形) "等符号。" L "表示该常量为长整型常量(long型)," U "表示该常量为无符号整型常量(unsigned型)," LU/ul "表示无符号长整型常量(unsigned long型)

//" L "、" U "不分大小写和顺序

LongNum=1000L;					/*L表示长整型*/
UnsignedNum=999u;				/*u表示无符号整型*/
UnsignedLongNum=99999ul;		 /*ul表示无符号长整形*/

C语言中任何一个整型常量都可以通过3种形式进行表达,并且不影响整数的数值,分别为:八进制数、十进制数、十六进制数

  • 八进制

    八进制数需要" 0 "来当作前缀,由正负号和数字0~7构成的

    octalNum=0777;					/*常数值前面加上" 0 "来代表八进制数*/
    
  • 十进制

    十进制是不需要在其前面添加前缀的,由0~9构成

    algorismNum=123;					/*声明十进制常数*/
    
  • 十六进制

    十六进制数以" 0x "或" 0X "开头,代表十六进制数。十六进制数由正负号和数字09以及字母AF构成

    //十六进制整型中字母不区分大小写

    hexNum1=0xFFF
    hexNum2=0Xfff
    

C语言中,整数数值都以二进制形式,并且以补码或反码的形式存放在内存中

补码就是空位补零,反码就是原有位" 0 "变" 1 "," 1 "变" 0 "

对于有符号整数,无论以哪种形式(补码、反码)存放在内存中,其都由" 符号位 "和" 数值位 "共同组成。" 符号位 "在内存中左边第一位,其余是" 数值位 "。若符号位内容为" 0 ",则代表该数值为正,若符号位内容为" 1 ",则代表该数值为负

一个正数补码后原码部分保持不变,一个负数的补码是将该数绝对值的二进制形式取反再加1

浮点型常量

浮点型常量又称" 实型常量 "、" 实型常数 "、" 实数 "。由整数部分和小数部分组成,用小数点进行隔开

表示浮点型常量的方式包括" 科学计数法 "、" 指数方式 "两种

科学计数法

科学计数法就是用十进制的小数方法描述浮点型变量

scienceNumber=123.999;					/*以科学计数法表示*/

指数

当浮点型常量非常大或者非常小时,科学计数法不利用观察,遂可以使用指数方式表示

指数表示方式由整数、位数、指数三部分构成

字母" E "或" e "进行指数显示

45e2=4500;					/*e2相当于10的2次方*/
45e-2=0.45;					/*e-2相当于10的-2次方*/

初始化浮点型常量时,可以加上修饰符," F "修饰符表示该常量是" float单精度 "类型," L "修饰符表示该常量是" long double长双精度"类型,不区分大小写

floatNum=1.12e2F;					/*初始化单精度类型*/
longDoublenum=9.123e-1L;					/*初始化双精度长类型*/
doubleNum=1.111e3;					/*默认双精度类型*/

//不加修饰符情况下,默认为双精度类型

字符型常量

字符型常量需要用单引号" ' "定界符来进行限制,字符型常量有三种," 字符型常量 "、" 无符号字符型常量 "、" 字符串型常量 "

C语言中实际上没有字符串型这个概念,可以初始化,但是并非有字符串这个类型,所以也就无法声明变量或常量,但是可以初始化实现字符串类型去临时使用

//空格也算一个字符

字符型常量只能是一个字符,不能是一串字符,内容可以是数字也可以是字母或符号

字符型常量区分发大小写

有符号字符型常量

char a='a';
char b='A';

定界符单引号" ' "不属于内容值的一部分

若数字被初始为字符,那就变成了字符,从而不能参与计算

无符号字符型常量

无符号字符型与字符型常量就在于,因为内存中所能存整型的长度不同,所以能转换为整型的大小不同

unsigned char a='255';

字符串型常量

字符串常量是被双引号" " "定界符包裹起来的若干字符序列,内容可以是数字也可以是字母或符号

如果字符串中一个字符也没有,则被称为空串(字符串的长度可以是0,即使没有内容,也会分配内存空间)

C语言中存储字符串常量时,末尾自动加" \0 "ASC字符字符当作字符串的结束标志,所以即使字符串的值为仅有1位,实际的长度则是2

//" \0 "ASC码字符是字符串的结束标志,系统自动添加

"welcome" -> |w|e|l|c|o|m|e|\0|

字符串类型与字符类型的存储方式不同,因为字符串末尾有字符串结束标志" \0 "

符号常量

符号常量是使用符号代替固定常量值的符号

在使用符号常量时,需要先进行声明(定义)

#define 符号常量名称 常量值					/*声明符号常量时不用以分号" ; "结尾*/
#define PI 3.14					/*注意符号常量与变量定义的区别,体会常量与变量的不同(逻辑、意义、内存空间)*/
printf("圆周率为:%f",PI)

符号常量的名称通常是大写,使用符号常量的好处是,若要对一些常量进行更改,只需要对声明时的符号常量修改即可

变量

变量就是在内存中找到一个适当的空间,并且给它命名,用来存放一个常量(确定目标,并提供存放的空间)

变量是在程序运行中,值可以改变的量

变量内存空间的长度取决于变量的类型

非数组元素的变量,被称为标量变量

声明变量

声明变量需要通过指定数据类型的关键字,加上" 变量标识符(变量名)列表 "进行声明

类型关键字 变量标识符列表

int a;			/*声明" a "为整型变量*/
double m,n;		/*声明" m "," n "为双精度浮点型变量*/
char c,d;		/*声明" c "," d "为字符型变量*/
void z;			/*声明" z "为空指针类型变量*/
  • 变量标识符只能由" 英文字母(A-Z,a-z) "、" 数字(0-9) "或者" 下划线组成(_) "
  • 变量标识符的开头,必须是" 字母 ",或者是" 下划线 ",不能是数字
  • 变量标识符区分大小写
  • 变量标识符不能与" 关键字 "相同

变量赋初值

声明变量时,可以为其赋一个初值,即把一个常数或者一个表达式的结果赋值给一个变量。变量中保存的内容就是这个常量或者赋值语句中表达式的值,这就是变量赋初值)(变量初始化)

类型 变量标识符=常数;
char a='9';

整型变量

整型变量是用来存储整型数值的变量

整型变量可以分为六种类型,基本整型使用关键字" int "进行变量声明,可以在此基础上加上一些符号进行修饰

类型名称 关键字 数值范围
有符号基本整型 [signed] int 4字节 | -32768~32767(16位系统)
无符号基本整型 unsigned [int] 4字节 | 0~65535(16位系统)
有符号短整型 [signed] short [int] 2字节 | -32768~32767
无符号短整型 unsigned short [int] 2字节 | 0~65535
有符号长整型 [signed] long [int] 4字节 | -2147483648~2147483647
无符号长整型 unsigned long [int] 4字节 | 0~4294967295
int a;
a=7;
unsigned short b=10;
long c=-4562;

浮点型变量

浮点型变量又称实型变量,是用来存储浮点型的变量,浮点型数值是由整数和小数两部分组成的

浮点型变量存储是以指数形式存储的

浮点型变量根据浮点型精度也可以分为三种类型,包括" 单精度类型 "、" 双精度类型 "、" 长双精度类型 "

类型名称 声明关键字 有效数字位 内存长度
单精度浮点类型 float 6~7位 4字节
双精度浮点类型 double 15~16位 8字节
双精度浮点长类型 long double 18~19位 16字节

字符型变量

字符型变量是存储字符常量的变量,一个字符型变量只能存储一个字符型常量(一个字符)

字符型变量存储字符型常量的过程,实际上是讲字符型常量内容的ASC码值(无符号整数)存储到内存单元中

有符号字符型变量在内存中占1个字节,取值范围是-128~127(1字节)

无符号字符型变量在内存中占1个字节,取值范围是-0~255(1字节)

声明有符号字符型变量的方法是使用关键字" char ",声明无符号字符型变量的方法是使用关键字" unsigned char "

char Cchar='1';					/*声明并初始有符号字符类型变量" Cchar "*/
unsigned char a='255';					/*声明并初始无符号字符类型变量" a "*/

因为字符型在内存中存储的ASC码是无符号整型,所以可以和整型(ASC码最大值小于有符号整型内存空间)或无符号整型进行相互转换(内存地址值相互存储)

//字符串类型在C语言中没有直接的存储变量

#指针型变量

局部变量

变量声明的位置不同,变量相对应的应用范围也就不同(产生了" 全局变量 "和" 局部变量 "之分)

一些变量在函数体内执行完就会消失,这种变量被称为" 局部变量 "(在函数内部声明的是" 局部变量 ")

" 局部变量 "只能在其所在的函数体内部使用(" 局部变量 "的应用范围是其所在的函数体,一旦离开则会报错)

全局变量

变量声明的位置不同,变量相对应的应用范围也就不同(产生了" 全局变量 "和" 局部变量 "之分)

函数体外部声明的变量为" 全局变量 ",全局变量的应用范围是其所在的整个" 源文件 "

静态全局变量

" 静态全局变量 "是只能在其所在源文件才能调用的" 全局变量 "

static int num=1;
int main()
{
return 0;
}

动态全局变量

" 动态全局变量 "是可以在所有" 源文件 "中都可以调用的" 全局变量 "

" 全局变量 "声明时,默认是" 动态全局变量 "(无需关键字)

变量存储

变量有很多不同的" 存储类型 ",可分为" 静态存储 "与" 动态存储 "

变量可以通过" 存储类修饰符 "来指定编译器如何存储变量,包括:" 自动(auto) "、" 静态(static) "、" 寄存器(register) "、" 外部(extern) "

根据变量的产生时间,变量可分为" 动态存储 "与" 静态存储 "

" 静态存储 "是程序运行时分配固定的存储方式;" 动态存储 "是程序运行期间,根据需要动态的分配存储空间

自动存储变量(auto)

" 自动存储变量 "为" 自动变量 "

" auto "关键字修饰一个局部变量为" 自动 ",程序每次执行到" auto "变量时,计算机都会产生一个新变量,并对其重新初始化

auto int num=123;

程序默认每个变量的存储方式是" auto "的

静态存储变量(static)

" 静态存储变量 "为" 静态变量 "

" static "关键字会使目标局部变量在语句块执行中始终保持初值(初始化只在第一次时生效),语句块执行中,变量将始终保持上一次赋值结果(函数结束静态变量不销毁)

int num()
{
	static int _num=1;
	printf("%d",_num);
	_num++;
	return 0;
}
int main()
{
	int count;
	scanf("请输出查验次数:%d",&count);
	while(count)
	{
		printf("第%d次值\n",count);
		num();
		puts("\n");
	}

	return 0;
}

" static "关键字用在变量时,与" 静态函数 "时的" static "关键字语义作用完全不同

寄存器存储变量(register)

" register "变量为" 寄存器存储变量 "

" register "变量将指定局部变量存放在计算机某个寄存器中(将频繁使用的变量声明为寄存器存储变量,可以提高运行效率,不经过内存,提升计算速度)

硬件寄存器不占用内存地址,遂无法获得寄存器存储变量的地址

有效使用寄存器存储变量,需要对寄存器的数量、种类以及工作方式有充分的了解(对可移植性程序不友好)

register int num=1;

外部存储变量(extern)

" extern "关键字声明了程序中,将要用到,但尚未初始化的全局变量(声明在另一个转换单元中初始化的变量)

主要用于多个用户协同合作,一个" 源文件 "中声明变量,另一个" 源文件 "初始化变量

数组

数组是类型相同、数目固定的若干个变量的有限集合(相同类型)

" 数组元素 "是组成数组的基本单元,必须具有相同的数据类型,并且" 数组名 "和" 下标 "是唯一的

" 数组元素 "又称" 下标变量 "(数组内的变量被称为下标变量,与之对应的一般变量,则被称为标量变量)

C语言中数组元素不支持变量,所以数组中存储的都是常量

数组是一种复杂数据类型,是有序数据的结合;有序是指系统在存放的时候会为数据元素分配一段连续的存储空间,数据元素在这段空间内按照先后顺序进行存放

数组名是用户定义的数组标识符

下标是数组中各个元素之间的相对位置

数组按照数组元素的类型,可将数组分为:" 整型数组 "、" 字符型数组 "、" 浮点数数组 "、" 指针数组 "等类型

  • 整型数组
  • 浮点型数组
  • 字符型数组
  • 指针型数组

数组按照下标的个数,可将数组分为:" 一维数组 "、" 二维数组 "、" 多维数组 ",C语言对数组的下标的数量没有限制

  • 一维数组
  • 二维数组
  • 多维数组

几维的维数是按照数组元素的下标个数进行区分的,有几个下标,数组就是几维

通常一维代表线性数据的组合,二维看作是平面数据的集合,多维数组则是多面体、三维动画、立体声、立方体等

声明数组

声明数组由" 类型说明符 "、" 数组标识符 "、" 中括号 "、" "四部分组成

类型说明符 数组标识符[常量表达式];
int Shmily[5];					/*声明一个名叫" Shmily "的整型数组,数组长度为5(0,1,2,3,4,)*/

" 类型说明符 "表示数组中的所有元素类型(是什么类型的数组),可以是任意一种简单类型、构造类型或指针

" 数组标识符 "表示这个数组型变量的名称(数组名),命名规则与变量名一致(字母、数字、下划线组成,必须以字母、下划线开头)

中括号(方括号)" [] "是数组类型必须的" 数组标志 "

中括号内的常量表达式必须为常量或符号常量,不能为变量

常量表达式定义了数组中存放的数据元素的个数,即" 数组长度 "

数组名不允许与其他变量名相同,唯一标识符

声明数组结尾需要加上分号" ; "

数组元素不能被整体引用,只能逐个元素引用

初始化数组

声明是在内存中为其分配空间,而初始化则是填入真正的内容

声明数组时可以直接对数组元素赋初值

int a[3]={1,2,3};					/*声明整型数组" a "时,同时赋初值1,2,3对应在数组下标0,1,2位置上*/
int b[5]={1,2,3};					/*声明整型数组" 5 "时,赋部分初值1,2,3对应数组下标0,1,2位置上,其余下标则不赋值*/

声明数组和初始化数组同时进行时可以不直接指定数组的长度

char c[]={'b','i','b','o','l','i'};					/*声明字符型数组并直接赋初值,因为同时赋初值所以没直接指定数组长度*/

后初始数组

如果先声明数组,但是并未初始化,需要在声明时确定数组长度

引用数组

引用数组由" 数组标识符 "和" 下标 "两部分组成

数组标识符[下标];
Shmily[3];					/*引用Shmily数组中的第4个变量*/

不管一维、二维还是多维的数组,在引用时,都不能" 越界 "

使用格式化字符串输出函数与数组配合打印字符数组

char k[]={'b','i','b','o','l','i'};
for(int x=0,x<=5,x++){printf("%c",k[x]);}

一维数组

数组元素只有一个下标的数组

#define i 5
int a[i];					/*声明名为" a "的整型数组,数组长度是5*/
int b[1+3+1];					/*声明名为" b "的整型数组,数组长度是5*/
int c[5];					/*声明名为" c "的整型数组,数组长度是5*/
总字节数=sizeof(类型)*数组长度					/*计算一维数组所需内存字节数的公式*/

二维数组

二维数组在一般一维数组的基础上,多了一个" 常量表达式 ";第二个常量表达式则在第一个常量表达式" 下标 "的基础上称作" 列下标 "

二维数组的两个表达式根据次序为:" 行下标 "、" 列下标 "

二维数组的元素也被称为" 双下标变量 ",引用二维数组的元素时,不能使用引用一维数组的方法(数组标识符[行下标]),而是要引用" 双下标变量 "( 数组标识符[下标][列下标])

类型说明符 数组标识符[常量表达式][常量表达式];
int Shmily[3][5];					/*声明一个3(行)5(列)的数组*/
int a[][5]={{1,2,3,4,5},{1,2,3,4,5},{1,2,3,4,5}};					/*声明一个3行5列的整型二维数组*/

二维数组在存储空间中是按行排列的,即按行顺次存放,先存放" 下标 "的一维的所有数组元素,再存放二维" 列下标 "的数组元素,每行中的元素也是依次存放的

在为所有元素赋初值时,可以省略" 行下标 "但不能省略" 列下标 "(在存储空间中,如果省略列下标,计算机将不知道列下标从哪里起始)

若赋初值时,大括号内的数据少于数组元素的个数时,没被赋值的数据将自动填0

int Shmily[2][2]={1,2,3,4};					/*整型二维数组2行2列赋初值,将所有数据都直接写在大括号内*/
int a[][3]={1,2,3,4,5,6};					/*省略行下标进行赋初值*/
int b[3][3]={
{1,2},
{1,2},
{1,2,3}
};					/*对部分数组元素赋值*/
char c[2][2];
c[0][0]='a';
c[0][1]='b';					/*先声明二维数据,再分开引用" 双下表变量 "进行赋值*/

多维数组

多维数组的声明与二维数组方法相同,只是下标更多

数据类型 数组标识符[常量表达式1][常量表达式2],...[常量表达式n];
int intity1[5][5][5];
char string1[3][3][3][3][3];					/*多维数组因为占用大量存储空间,所以通常很少用到*/

字符串赋初值

可以直接用字符串的形式给字符数组直接赋初值,用于存放一整个字符串

char stra[]={"biboli"};
char strb[]="biboli";					/*两种形式直接将字符串赋初值给字符数组*/

字符串在保存时,字符串总是以" \n "作为结束符;当字符串传入数组时,也会把结束符" \0 "存入数组,比以此作为该字符串结束的标志(系统自动添加)

用字符串方式赋值比用字符逐个赋值要多占1字节,多占的这个字节用于存放字符串结束标志" \0 "

字符串在存储空间

char cstr[]={'b','i','b','o','l','i','\n'};					/*为了处理方法一致,便于测定字符串的实际长度,字符数组最好手动加上转义" \0 "*/

字符

字符常量分为" 一般字符常量 "," 转义字符常量 "

//一般字符常量和转义字符常量都属于字符类型

一般字符

一般字符常量指的是字母、数字和符号

A-Za-z0-9
?><":|}{}"+_)(*&^%$#@!~?》《“:|}{+——)(*&……%¥#@!~
中文

转义字符

特殊字符常量也称" 转义字符 ",每个转义字符具有特定的含义,可将" \ "后面的字符转换为其他功能的意思,遂称" 转义字符 "

转义字符的格式是以" \ "开头,加上一个或几个的一般字符,共同组成

转义字符在输出中不显示

\		(\)			单一个" \ "则代表着忽略" \ "的存在,并将下一行作为上一行的延续
\a		(BEL)		响铃
\b		(BS)		退格
\f		(FF)		换页
\n		(LF)		换行
\r		(CR)		回车
\t		(HT)		水平制表
\v		(VT)		垂直制表
\\		(\)			反斜杠
\'		(')			单引号
\"		(")			双引号
\?		(?)			句号
\0		(NULL)		空字符
\ddd				产生1至3位八进制数大小的任意字符
\xhh				产生1到2位十六进制大小的任意字符

类型转换

隐式类型准换

int与unsigned int隐式转换_yin的博客-CSDN博客

不同的数据类型可以相互转换(注意内存空间)

不同数据类型之间混合运算,需要先转换为同一数据类型再做运算

赋值运算过程中,如果赋值号两边的数据类型不同,赋值号右边的数据类型比赋值号左边的精度要高,则最终赋值结果会降低精度,丢失的数据会被四舍五入后输出(隐式转换)

强制类型转换

对于隐式类型转换或表达式类型转换时,如果编译器发出提示告警信息,则可以使用强制类型转换,编译器就不会出现提示告警信息了

强制类型转换的一般形式,是在变量或常量前使用被括号包裹,要强制转换类型的表达式:(强制转换类型)表达式

(强制转换类型)变量(常量)
float f=9.999;
int i=(int)f;					/*进行强制类型转换*/

//强制类型转换中,如果高级别赋给低级别,最终高级别会造成丢失(部分)

强制类型转换函数

const_cast , static_cast , dynamic_cast , reinterpret_cast

posted @ 2021-05-11 16:24  biboli  阅读(154)  评论(0编辑  收藏  举报