最近复习巩固了C语言的部分知识,整理了其中关于变量与数据类型的知识点,记录下来。
变量
在C语言中,变量存放在内存中,在内存中存取数据要明确三件事情:数据存储在哪里、数据的长度以及数据的处理方式。
变量名不仅仅是数据的标识符,同时告诉了我们数据存储的地址;而数据类型则指明了数据的长度和处理方式。
C语言中共有6中基本数据类型,分别是char、short、int、long、float、double,它们的长度和取值范围一般如下:
可以使用以下代码打印它们各自的字节数。
#include <stdio.h>
int main()
{
printf("sizeof(char) = %d\n", sizeof(char));
printf("sizeof(short) = %d\n", sizeof(short));
printf("sizeof(int) = %d\n", sizeof(int));
printf("sizeof(long) = %d\n", sizeof(long));
printf("sizeof(float) = %d\n", sizeof(float));
printf("sizeof(double) = %d\n", sizeof(double));
return 0;
}
八进制、十进制与十六进制
在C语言中,整数可以使用八进制、十进制、十六进制表示。
八进制:八进制由0– 7八个数字组成,使用时必须以0开头,例如:
int a = 015; int b = 027; int c = 071;
十进制:十进制由0-9十个数字组成,使用时没有任何前缀,和我们日常使用相同。
十六进制:十六进制由数字0-9、字母A-F或a-f组成,使用时必须以0x或者0X开头,例如:int
a = 0x45f; int b = 0xffee; int c = 0xa0;
示例代码如下:
#include <stdio.h>
int main()
{
short a = 110; //十进制数字
int b = 02713; //八进制数字
long c = 0X1DAB83; //十六进制数字
printf("八进制:a=%#ho, b=%#o, c=%#lo\n", a, b, c); //以八进制形似输出
printf("十进制:a=%hd, b=%d, c=%ld\n", a, b, c); //以十进制形式输出
printf("十六进制:a=%#hx, b=%#x, c=%#lx\n", a, b, c); //以十六进制形式输出(字母小写)
printf("十六进制:a=%#hX, b=%#X, c=%#lX\n", a, b, c); //以十六进制形式输出(字母大写)
return 0;
}
其中输出格式控制符中加入#号是为了输出进制前缀。
有符号数与无符号数
在C语言中,整数可分为有符号数和无符号数。
对于有符号数:最高位为1,表示这个数为负数;最高位为0,表示这个数为正数。
在计算机内部用补码表示有符号数
正数的补码就是它本身,负数的补码是它的绝对值取反加1
对于无符号数:在计算机内部用原码表示无符号数
对于固定大小的无符号数:有最大值加1等于最小值,最小值减1等于最大值
例:1111 1111+1=0; 0-1=1111 1111;
无符号数和有符号数混合运算,有符号数被强制转换成无符号数。
示例代码如下:
#include<stdio.h>
int main()
{
short a = 0100; //八进制
int b = -0x1; //十六进制
long c = 720; //十进制
unsigned short m = 0xffff; //十六进制
unsigned int n = 0x80000000; //十六进制
unsigned long p = 100; //十进制
//以无符号的形式输出有符号数
printf("a=%#ho, b=%#x, c=%lu\n", a, b, c);
//以有符号数的形式输出无符号类型(只能以十进制形式输出)
printf("m=%hd, n=%d, p=%ld\n", m, n, p);
return 0;
}
float与double
在C语言中,实数有float和double两种存储方式,这两种存储方式被统称为浮点数。
浮点数在内存的存储方式为:符号位+指数+尾数。
浮点数的存储转换:将实数转换成二进制;用指数形式表示实数;计算指数偏移后的值。
注意:计算指数时需要加上偏移量,而偏移量的值与类型有:float的偏移量为127,double的偏移量为1023
例如实数8.25在内存中的float的表示:
二进制:1000.01 -> 指数形式:1.00001*2^3。
因此,符号位为0;指数位为3+127=130,二进制表示为:10000010;尾数位为00001。
总的内存float表示:01000001000001000000000000000000
-> 0x41040000
同样都是4个字节,为什么float型数据表示的范围比int型大?
float能表示的具体数字的个数与int相同
float能表示的数字之间不是连续的,存在间隙。
浮点数只是一种近似的表示法,不能作为精确数使用。
同时由于内存表示法相对复杂,浮点数的运算速度比int慢得多
类型转换
在C语言中,数据可进行自动类型转换和强制类型转换
自动类型转换方向图如下:
会发生自动类型转换的几种情况:1. 算术表达式中,低类型转换为高类型;2. 赋值表达式中,表达式的值转换为左边变量的值;3.函数调用时,实参转换为形参的类型;4.函数返回值,return表达式转换为返回值类型
自动类型转换是编译器默默地、隐式地进行的一种类型转换。
强制类型转换是由程序员主动提出,通过特定格式的代码指明的一种类型转换。
强制类型转换的格式为:(typename)expression
使用强制类型转换的风险一般比较高,程序员需要自己好好把控。
无论是自动类型转换还是强制类型转换,都只是为了本次运算而进行的临时性转换,转换的结果也会保存到临时的内存空间,不会改变数据本来的类型或者值。
变量属性
在C语言中,变量可以有自己的属性
在定义变量的时候可以加上属性关键字,属性关键字指明变量的特有意义
auto 变量:auto即C语言中变量的默认属性
register 变量:register关键字指名将局部变量存储于寄存器上;register只是请求将变量存储在寄存器,不一定请求成功;register变量必须是cpu寄存器可以接受的值;不能用&运算符取register变量的地址;register关键字不能申明全局变量
static变量:static修饰的变量存放在静态变量区,但它的生命期与全局变量相同;static关键字同时有作用域限定符的意义,static修饰的全局变量作用域只是在声明的文件中,static修饰的函数作用域只是在声明的文件中
extern变量:extern用于声明“外部”定义的变量和函数;extern变量在文件的其他地方分配空间;extern变量在文件的其他地方定义;extern用于告诉编译器用标准C方式编译