目录
变量
常量
拓展
整型
实型
布尔
字符
变量含义 -> 程序运行期间可能会出现变动的值,称为变量(variable)
变量本质 -> 变量相当于给一块内存区域(定长)起个别名,操作变量就等于操作对应内存
变量定义
语法格式 -> 数据类型 变量名 = 初始值;
变量名称为标识符,定义规则如下
随堂代码
#include
#include
int main()
{
//变量定义
//数据类型 变量名;
int Age;
//变量赋值
Age = 18;
//变量定义及初始化
//数据类型 变量名(标识符) = 初始值;
//初始化(initialize)变量赋初始值
int Money = 0;
return 0;
}
变量声明 -> extern int a; -> 不占用内存空间
变量定义 -> int a; -> 占用内存空间
随堂代码
#include
#include
int main()
{
//变量定义 -> 占用内存空间
int a;
a = 1;
//变量声明 -> 不占内存空间
extern int b;
//发生错误 -> 无法解析的外部符号_b
b = 2;
return 0;
}
类型限定符
常量含义 -> 程序运行期间不会改变的值称为常量(constant)
常量作用 -> 常量作用于记录程序固定的值
常量特性 -> 常量默认是不允许修改的(IDE限制 / 内存属性限制) - 将常量内存地址对应物理页属性(R/W)修改后即可随意更改常量值
常量表现
常量类型 | 表现形式 |
---|---|
整数常量 | 100 - 200 |
小数常量 | 3.14 - 1.23 |
字符常量 | ‘a’ - 'c' |
字符串常量 | "Hello" |
宏常量 | #define Age 18 |
const修饰的变量 | cosnt int Age 18 |
const 修饰的变量
变量原有特性的基础之上增加修改限制
语法规则 -> const 数据类型 常量名 = 初始值;
随堂代码
#include
#include
//全局变量
const int G_Num = 10;
int main()
{
//局部变量 -> 存储在当前线程栈区中(可读可写)
int a = 0;
a = 1;
//const 数据类型 常量名 = 初始值;
const int Ver = 1;
//编译器限制 -> 表达式必须是可修改的左值
Ver = 2;
//编译器限制 == 内存属性限制
G_Num = 2;
return 0;
}
突破常量限制
编译器
内存
全局常量对应内存地址属性为只读(ONLY READ)
只读内存尝试写入时会发生异常
通过API修改对应内存属性为PAGE_READWRITE(可读可写)
VirtualProtect(内存地址, 修改大小, 内存属性, 默认属性);
代码示例(修改内存属性)
#include
#include
#include
//全局常量 -> 内存属性只读(ONLY READ)
const int g_Num = 1;
int main()
{
/*
函数原型
BOOL VirtualProtect(
[in] LPVOID lpAddress, //修改内存地址
[in] SIZE_T dwSize, //修改内存大小
[in] DWORD flNewProtect, //修改内存属性
[out] PDWORD lpflOldProtect //默认内存属性
);
*/
//默认数据
DWORD dwOld = 0;
//修改属性
VirtualProtect(&g_Num, sizeof(g_Num), PAGE_READWRITE, &dwOld);
//指针类型
int* p = &g_Num;
//操作内存
*p = 100;
//恢复属性
VirtualProtect(&g_Num, sizeof(g_Num), dwOld, &dwOld);
return 0;
}
物理页
示例代码
#include
#include
#include
//全局常量 -> 内存属性只读(ONLY READ)
const int g_Num = 1;
int main()
{
printf("Addr -> 0x%016llx Data-> %d", &g_Num, g_Num);
system("pause");
int* p = &g_Num;
*p = 0x100;
printf("Addr -> 0x%016llx Data-> %d", &g_Num, g_Num);
system("pause");
return 0;
}
操作过程
数据类型 -> 变量分配对应大小的内存空间以及存储规则
整数类型 -> 正数-负数-0-(整数不存在小数部分)
数据类型 | 内存大小 |
---|---|
char | 1BYTE(08BIT) |
short | 2BIYE(16BIT) |
int | 4BYTE(32BIT) |
long | 4BYTE(32BIT) |
long long | 8BYTE(64BIT) |
变量定义
#include
#include
int main()
{
//数据类型 变量名 = 初始值;
char c = 1;
short s = 2;
int i = 3;
long l = 4;
long long ll = 5;
return 0;
}
变量输出
格式化字符串 | 含义 |
---|---|
%d | 输出有符号十进制数 |
%u | 输出无符号二进制数 |
%o | 输出八进制数 |
%x | 输出十六进制数 |
%hd | short |
%ld | long |
%lld | long long |
%hu | unsigned short |
%lu | unsigned long |
%llu | unsigned long long |
#include
#include
int main()
{
//数据类型 变量名 = 初始值;
char c = 65;
short s = 2;
int i = 3;
long l = 4;
long long ll = 5;
//整型输出
printf("%c \r\n", c);
printf("%hd \r\n", s);
printf("%d \r\n", i);
printf("%ld \r\n", l);
printf("%lld \r\n", ll);
return 0;
}
正负数
无符号 - unsigned
有符号 - signed
定义整数类型变量时不增加前缀默认均为signed
取值范围
signed
数据类型 | 内存大小 | 取值范围 |
---|---|---|
char | 1BYTE | -27 ~ 27-1 |
short | 2BYTE | -215 ~ 215-1 |
int | 4BYTE | -231 ~ 231-1 |
long | 4BYTE | -231 ~ 231-1 |
long long(__int64) | 8BYTE | -263 ~ 263-1 |
unsigned
数据类型 | 内存大小 | 取值范围 |
---|---|---|
unsigned char | 1BYTE | 0 ~ 28-1 |
unsigned short | 2BYTE | 0 ~ 216-1 |
unsigned int | 4BYTE | 0 ~ 231-1 |
unsigned long | 4BYTE | 0 ~ 231-1 |
unsigned long long(__int64) | 8BYTE | 0 ~ 263-1 |
随堂代码
#include
#include
int main()
{
//有符号 %d
signed int a = 4294967295;
printf("%d \r\n", a);
//无符号 %u
unsigned int b = 4294967295;
printf("%u \r\n", b);
return 0;
}
数字越界
数据溢出
#include
#include
int main()
{
//2BYTE最大的正数 0x00007FFF
short num = 32767;
printf("%hd \r\n", num);
//2BYTE最小的负数 0xFFFF8000
num++;
printf("%hd \r\n", num);
return 0;
}
精度丢失
#include
#include
int main()
{
//1BYTE -> 8BIT
//1HEX -> 4BIN
//无符号4字节能够存储最大的正数 0xFFFFFFFF
unsigned int num = 4294967295;
printf("%u \r\n", num);
//4294967295 + 1 = 4294967296
//0xFFFFFFFF + 0x1 = 0x100000000
num++;
printf("%u \r\n", num);
return 0;
}
数据类型大小
语法规则 -> sizeof(变量/类型);
随堂代码
#include
#include
int main()
{
printf("int size -> %d \r\n", sizeof(int/*数据类型*/));
long long ll;
printf("long long size -> %d \r\n", sizeof(ll/*变量名*/));
return 0;
}
整数常量
整数类型变量或者常量赋值时等号后边初始值为整数常量
整数常量可以添加前缀或者后缀来修改其含义
前缀
进制 | 表达 | |
---|---|---|
(BIN)二进制 | 0b + 二进制数 | 0b11111111 |
(OCT)八进制 | 0 + 八进制数 | 0377 |
(DEC)十进制 | 十进制数 | 255 |
(HEX)十六进制 | 0x + 十六进制数 | 0xFF |
#include
#include
int main()
{
printf("%d \r\n", 0b11111111); //BIN 二进制
printf("%d \r\n", 0377); //OCT 八进制
printf("%d \r\n", 255); //DEC 十进制
printf("%d \r\n", 0xFF); //HEX 十六进制
return 0;
}
后缀
符号 | 含义 |
---|---|
L\l | long |
LL\ll | long long |
U\u | unsigned |
10 int
10L long
10LL long long
10U unsigned int
10UL unsigned long
10ULL unsigned long long
实型也称作浮点型-也就是数学当中的小数-即存储小数的数据类型
整数与小数在计算机中存储规则截然不同-1.0与1虽然在数值上完全一样但是其存储方式不同
整数类型按照补码存储
小数类型按照IEEE规则将浮点数分为指数部分与小数部分存储
整数没有小数部分-浮点数存在小数部分
浮点型类型
单精度浮点数float - 4Byte
双精度浮点数double- 8Byte
double类型比float类型所表示的浮点数更精确
类型 | 大小 | 有效范围 |
---|---|---|
float | 4 | 7位有效数字 |
double | 8 | 15 ~ 16位有效数字 |
浮点数变量
常规定义
#include
#include
int main()
{
//小数常量后增加f当作float类型处理
float f = 3.14f;
printf("size of float -> %d \r\n", sizeof(f));
double d = 3.14;
printf("size of double -> %d \r\n", sizeof(double));
return 0;
}
科学计数
#include
#include
int main()
{
//科学计数法
//3 * 10^2
float f = 3e2f;
printf("%f \r\n", f);
//3 * 0.1^2
double d = 3e-2f;
printf("%lf \r\n", d);
return 0;
}
浮点数输出
float - %f
double - %lf
%.2f保留有效位数
%e输出指数计数法的浮点数
#include
#include
int main()
{
//小数常量后增加f当作float类型处理
float f = 3.1415926f;
printf("size of float -> %d \r\n", sizeof(f));
printf("float -> %f \r\n", f);
double d = 3.1415926;
printf("size of double -> %d \r\n", sizeof(double));
printf("double -> %lf \r\n", d);
//限制输出位数
printf("%.3f \r\n", f);
return 0;
}
浮点数存储
示例代码
#include
#include
int main()
{
float f = 12.25f;
//0x41440000
return 0;
}
存储规则
将12.25转换成为二进制数
整数部分12 == 1100
小数部分0.25 == 01
转换数据1100.01
移动小数点使小数点前面只有一个有效位 -> 小数点向左移动3位(左加右减 - 127) == 130(指数部分) == 1.10001(尾数部分)
符号位(31 ~ 31) -> 0
指数位(30 ~ 23) -> 1000 0010
尾数位(22 ~ 00) -> 1000 1000 0000 0000 0000 000
拼接二进制数据 -> 0100 0001 0100 0100 0000 0000 0000 0000 -> 0x41440000
布尔类型代表真或者假
true为真
false为假
bool类型占用内存大小为1字节
#include
#include
#include
int main()
{
bool b;
printf("sizeof bool -> %d \r\n", sizeof(b));
//1
b = true;
printf("true -> %d \r\n", b);
//0
b = false;
printf("false -> %d \r\n", b);
printf("bool -> %d \r\n", 1 + 1 > 0);
return 0;
}
语法 -> char ch = 'a';
作用 -> char类型通常用于存储字符(字母-数字-符号)
注意事项
初始化字符变量时,需要将内容放在单引号内
单引号内只能有一个字符
单引号内可以填写字符数字字母
字符变量不是将字符存储在内存中而是按照对应的编码格式存储
char类型通常用于存储字母但也可以按照整数类型表示
char类型占用内存大小为一字节
从底层角度考虑char类型也为整数类型存储字符等均按照整数存储
#include
#include
int main()
{
//字符放在单引号内
//单引号内只能填写一个字符
//单引号内只能写字母 数字 字符
char ch = '1';
printf("%d \r\n", ch);
printf("%c \r\n", ch);
//ASCII -> 2 -> 50
char ch1 = 50;
printf("%d \r\n", ch1);
printf("%c \r\n", ch1);
printf("size of char -> %d \r\n", sizeof(char));
return 0;
}
字符存储
计算机只认识二进制,字符'A'存储不是将A存放在内存中,而是将字符'A'对应的ASCII码值存放在内存里
ASCII表
字符输入
#include
#include
int main()
{
char ch;
int i;
//字符输入
scanf_s("%c", &ch);
printf("%c \r\n", ch);
//整数输入
scanf_s("%d", &i);
printf("%c \r\n", i);
return 0;
}
字符转换
#include
#include
int main()
{
//'A' -> 65
//'a' -> 97
char ch = 'a';
printf("%c \r\n", ch - 32);
return 0;
}