这是我在学习中的一个小问题,希望对你也有所帮助:
问:数据类型和简单变量属于oop的基本概念吗?
答:不是!数据类型和简单变量本身并不属于面向对象编程(OOP)的基本概念,但它们是编程中的基础概念,面向对象编程会基于这些基础概念来构建更复杂的结构。
好的,步入正题:
一、简单变量
1.概述变量
变量来源于数学,是计算机语言中能储存计算结果或能表示值的抽象概念。
简单点,可以把变量想象成一个带名字的盒子,这个盒子可以用来存放不同的东西。
- 变量名:就像在盒子外面贴了个标签,方便你知道这个盒子是用来装什么的,随时可以通过名字找到它。
- 数据:盒子里面可以装数据,比如数字、文字等。你可以随时往盒子里放新的东西,或者取出盒子里的内容来使用。
int num = 5;
比如,以上代码,你可以理解为:
- 给盒子取了个名字叫 num。
- 这个盒子专门用来装整数(因为 int 表示“整型”)。
- 你把数字 5 放进了这个名叫 num 的盒子里。
以后你想要使用这个 5,只要提到 num,就能知道这个名字对应的盒子里装着的是 5。
把信息储存在电脑中,需要解决以下几个问题:
- 信息将储存在哪里;
- 要储存什么值;
- 储存何种类型的信息。
int num;
num = 5;
这个程序很简单,就是声名一个整数函数 num,再给它赋值为 5。
但是,它背后的原理是怎样的呢?
1.变量声明
- 数据类型声明:int 表示变量 num 是一个整型变量,用来存储整数。
- 内存分配:程序会在内存中为这个整型变量分配存储空间。对于32位的编译器来说,int 一般占用4字节(32位)的内存(这是后话)。
- 未初始化:此时,num 没有被赋值,里面存储的是未定义的垃圾值。
2.变量赋值
- 将值存入内存:程序会将整数 5 以二进制形式存储到前面为 num 预留的内存空间中(比如,
5
在二进制中表示为 0000 0000 0000 0000 0000 0000 0000 0101)。 - 覆盖之前的值:如果 num 中之前有任何值(垃圾值),它将被新的值 5 覆盖。
有关内存等的信息,我们将在下一章的指针中介绍。
2.变量名
-
在名称中只能使用字母字符、数字和下划线(_)。
-
名称的第一个字符不能是数字。
-
区分大写字符与小写字符。
-
不能将C++关键字用作名称。
-
以两个下划线或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用以一个下划线开头的名称被保留给实现,用作全局标识符。
-
C++对于名称的长度没有限制,名称中所有的字符都有意义,但有些平台有长度限制。
倒数第二点与前面几点有些不同,因为使用像_time_stop或_Donut这样的名称不会导致编译器错误,而会导致行为的不确定性。换句话说,不知道结果将是什么。不出现编译器错误的原因是,这样的名称不是非法的,但要留给实现使用。全局名称指的是名称被声明的位置,这将在第4章讨论。
命名方案
变量命名方案和函数命名方案一样,也有很多话题可供讨论。确实,该主题会引发一些最尖锐的反对意见。同样,和函数名称一样,只要变量名合法,C++编译器就不会介意,但是一致、精确的个人命名约定是很有帮助的。
与函数命名一样,大写在变量命名中也是一个关键问题(参见第2章的注释“命名约定”),但很多程序员可能会在变量名中加入其他的信息,即描述变量类型或内容的前缀。例如,可以将整型变量myWeight命名为nMyWeight,其中前缀n用来表示整数值,在阅读代码或变量定义不是十分清楚的情况下,前缀很有用。另外,这个变量也可以叫做intMyWeight,这将更精确,而且容易理解,不过它多了几个字母(对于很多程序员来说,这是非常讨厌的事)。常以这种方式使用的其他前缀有:str或sz(表示以空字符结束的字符串)、b(表示布尔值)、p(表示指针)和c(表示单个字符)。
随着对C++的逐步了解,将发现很多有关前缀命名风格的示例(包括漂亮的m_lpctstr前缀—这是一个类成员值,其中包含了指向常量的长指针和以空字符结尾的字符串),还有其他更奇异、更违反直觉的风格,采不采用这些风格,完全取决于程序员。在C++所有主观的风格中,一致性和精度是最重要的。请根据自己的需要、喜好和个人风格来使用变量名(或必要时,根据雇主的需要、喜好和个人风格来选择变量名)。
拓展:
C++ 关键字列表
alignas decltype namespace struct alignof default new switch and delete noexcept template and_eq do not this asm double not_eq thread_local auto dynamic_cast nullptr throw bitand else operator true bitor enum or try bool explicit or_eq typedef break export private typeid case extern protected typename catch false public union char float register unsigned char16_t for reinterpret_cast using char32_t friend return virtual class goto short void compl if signed volatile const inline sizeof wchar_t constexpr int static while const_cast long static_assert xor continue mutable static_cast xor_eq
二、数据类型
1.整型
1.整型概论
整形就是没有小数部分的数字。小学生都知道,没有最大的整数,但是,在 C++ 当中,整型只能表示整数的子集,也就是说,整型只能表示整数的一部分。
并且, C++ 中不同的整形所占用的内存量也不同。表示整数值的范围越广,占用内存也越大。术语宽度用于描述储存整数时使用的内存量。使用内存越大,就越宽。
C++ 的整形按宽度(递增)排列为:
- char
- short
- int
- long
- long long(C++11 新增)
并且 C++ 中的整形分为有符号类型和无符号类型。无符号类型的范围是从 0 开始,而有符号类型则可以表示负数。比如,一个 32 位的 int 类型(有符号)可以表示的范围是 -2147483648 到2147483647 ,而对应的 unsigned int 范围是 0 到 4294967295。
2.有符号类型
1.(整型 short、int、long、 long long、etc.)
整型 short、int、long 和 long long 都是有符号类型。
既然他们都是表示有符号的整形,那么他们的区别在于他们的最小长度不同。
- short 至少 16 位;
- int 至少和 short 一样长;
- long 至少 32 位,且至少与 int 一样长;
- long long 至少 64 位,且至少与 long 一样长。
最小长度
数据类型的最小长度就是指某种数据类型在电脑内存中最少占用的空间。简单说,每种数据类型都是一个“容器”,而最小长度就是这个“容器”在内存里占的大小。
比方说,如果你声明一个变量为 int 类型,那么它的最小长度通常是 4 字节(32位),无论你存储的是 0 还是 2147483647,它都会占用 4 个字节。而如果你用的是 short 类型,它只需要 2 字节,在某些场景下可以节省内存。
最小长度决定了你在内存中要用多大空间来存储数据。小数据类型用的空间少,大数据类型用的空间多,选对合适的数据类型能让程序跑得更快、更省内存。
位与字节
计算机内存的基本单元是位(bit)。可以将位看作电子开关,可以开,也可以关。关表示值 0,开表示值 1。8 位的内存块可以设置出 256 种不同的组合,因为每一位都可以有两种设置,所以8位的总组合数为 2×2×2×2×2×2×2×2,即 256。因此,8 位单元可以表示0 ~ 255或者-128 ~ 127。每增加一位,组合数便加倍。这意味着可以把 16 位单元设置成 65536个不同的值,把 32 位单元设置成 4294672296 个不同的值,把64位单元设置为18446744073709551616 个不同的值。作为比较,unsigned long存储不了地球上当前的人数和银河系的星星数,而 long long 则可以。
字节(byte)通常指的是8位的内存单元。从这个意义上说,字节指的就是描述计算机内存量的度量单位,1KB等于1024字节,1MB等于1024KB。然而,C++对字节的定义与此不同。C++字节由至少能够容纳实现的基本字符集的相邻位组成,也就是说,可能取值的数目必须等于或超过字符数目。在美国,基本字符集通常是 ASCII 和 EBCDIC 字符集,它们都可以用8位来容纳,所以在使用这两种字符集的系统中,C++ 字节通常包含8位。然而,国际编程可能需要使用更大的字符集,如 Unicode,因此有些实现可能使用16位甚至32位的字节。有些人使用术语八位组(octet)表示8位字节。
声明变量则需要声明语句,声明语句是已知知识,不再赘述。
2.char
char 是比较特殊的无符号类型。它既能表示小整数,又能表示字符。
虽然 char 类型通常用于表示单个字符,但它实际上是一个整数类型,本质上表示一个 8位(1字节)的整数。因此,它不仅可以表示单个字符,还可以存储相应的整数值。
在C++中,char 通常用于存储单个字符。例如:
char letter = 'A';
这里 letter 变量存储了字符 'A'。字符 'A' 在ASCII编码中对应的整数值是65,所以本质上,char 变量存储的是整数65。
由于 char 实际上是一个8位整数类型,它可以存储从 -128 到 127(有符号)或 0 到 255(无符号)的整数值。例如:
char num = 65;
std::cout << num; // 输出:A
3.运算符 sizeof、头文件 limits 和初始化
# include <iostream>
# include <climits>
int main()
{
using namespace std;
int n_int = INT_MAX;
short n_short = SHRT_MAX;
long n_long = LONG_MAX;
long long n_llong = LLONG_MAX;
cout << "int is " << sizeof(int) << " bytes." << endl;
cout << "short is " << sizeof n_short << " bytes." << endl;
cout << "long is " << sizeof n_long << " bytes." << endl;
cout << "long long is " << sizeof n_llong << " bytes." << endl;
cout << endl;
cout << "Maximum values:" << endl;
cout << "int: " << n_int << endl;
cout << "short: " << n_short << endl;
cout << "long: " << n_long << endl;
cout << "long long: " << n_llong << endl;
cout << "Minimum int value = " << INT_MIN << endl;
cout << "Bits per byte = " << CHAR_BIT << endl;
}
以下是输出:
int is 4 bytes.
short is 2 bytes.
long is 4 bytes.
long long is 8 bytes.
Maximum values:
int: 2147483647
short: 32767
long: 2147483647
long long: 9223372036854775807
Minimum int value = -2147483648
Bits per byte = 8
1.运算符 sizeof
sizeof 运算符是 C++ 中的一个关键字,用来计算数据类型或变量在内存中占用的字节数。它告诉你某个数据类型或对象在内存里到底占用了多少空间。
通俗地来讲,sizeof 运算符就像是测量“盒子”大小的工具,它能告诉你不同类型的数据在内存中占用的大小(字节数)。
例如,我们可以用 sizeof 计算数据类型的大小,这时数据类型应该放在圆括号中;同时,我们也可以用 sizeof 计算变量名,这时括号是可选的。
int a;
sizeof (int);
sizeof a
2.头文件 limits
前面说过,iostream是C++中用于数据的流式输入与输出的头文件。所以 sizeof 不在这个头文件里。所以在程序的一开始,我们就添加了 climits 头文件,这个头文件提供了各种整数类型的大小。
climits 是 C++ 中的一个头文件,提供了与整数类型相关的各种限制和边界值。这些限制定义了各类整数数据类型所能表示的最小值和最大值。
climits 头文件包含了一组常量,它们定义了不同类型的整数(如 int、char、long 等)的取值范围。通过这些常量,程序可以知道不同整数类型的上限和下限。
climits 中的符号常量(部分)
符号常量 | 表示 |
---|---|
CHAR_BIT | char的位数 |
CHAR_MAX | char的最大值 |
CHAR_MIN | char的最小值 |
SCHAR_MAX | signed char的最大值 |
SCHAR_MIN | signed char的最小值 |
UCHAR_MAX | unsigned char的最大值 |
SHRT_MAX | short的最大值 |
SHRT_MIN | short的最小值 |
USHRT_MAX | unsigned short的最大值 |
INT_MAX | int的最大值 |
INT_MIN | int的最小值 |
UINT_MAX | unsigned int的最大值 |
LONG_MAX | long的最大值 |
LONG_MIN | long的最小值 |
ULONG_MAX | unsigned long的最大值 |
LLONG_MAX | long long的最大值 |
LLONG_MIN | long long的最小值 |
ULLONG_MAX | unsigned long long的最大值 |
FLT_MANT_DIG | float 类型的尾数 |
FLT_DIG | float 类型的最少有效数字位数 |
FLT_MIN_10_EXP | 带有全部有效数的float类型的负指数的最小值(以10为底) |
FLT_MAX_10_EXP | float类型的正指数的最大值(以10为底) |
FLT_MIN | 保留全部精度的float类型正数最小值 |
FLT_MAX | float类型正数最大值 |
符号常量—预处理器方式
climits 文件中包含与下面类似的语句行:
#define INT MAX 32767
在C++编译过程中,首先将源代码传递给预处理器。在这里,#define和#include一样,也是一个预处理器编译指令。该编译指令告诉预处理器:在程序中查找INT_MAX,并将所有的INT_MAX都替换为32767。因此#define编译指令的工作方式与文本编辑器或字处理器中的全局搜索并替换命令相似。修改后的程序将在完成这些替换后被编译。预处理器查找独立的标记(单独的单词),跳过嵌入的单词。也就是说,预处理器不会将PINT_MAXTM替换为P32767IM。也可以使用#define来定义自己的符号常量(参见程序清单3.2)。然而,#define编译指令是C语言遗留下来的。C++有一种更好的创建符号常量的方法(使用关键字const,将在后面的一节讨论),所以不会经常使用#define。然而,有些头文件,尤其是那些被设计成可用于C和C++中的头文件,必须使用#define。
3.初始化
来自 C 语言:
int num = INT_MAX;
int uncles = 5;
int aunts = uncles;
int cousins = uncles + aunts + 5;
来自 C++:
int students = 101;
int teachers(50);
来自 C++ 11:
int books{8};
int pens = {19};
3.无符号类型
与有符号类型相对的数据类型是无符号类型。有符号类型可以表示正数、负数和零,而无符号类型只能表示非负整数(正数和零)。
unsigned short change;
unsigned int rovert;
unsigned quarterback;
unsigned long gone;
unsigned long long lang_lang;
与有符号类型相似。
4.整型溢出(如何选择整形数据类型)
一般来说,编程中尽量选择 int 类型,如果要表示很大的数据,就要选择 long 以至于 long long。如果需要节省内存(例如在嵌入式开发中),就要选择 short 以至于 char。同样,如果确定数据不会有负数,则选择无符号类型。
之前我们提到,整形有表示数据的范围。这时候,有的好奇宝宝要问了:如果小于或大于这个范围怎么办呢?
我们可以编写这个有趣的程序:
#include <iostream>
#define ZERO 0 // make zero symbol for 0 value
#include <climits>
int main()
{
using namespace std;
short sam = SHRT_MAX;
unsigned short sue = sam; // okay is variable sam already defined
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollar deposited." << endl << "Add $1 to each account." << endl;
cout << "Now ";
sam = sam + 1;
sue = sue + 1;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited." << endl << "Poor Sam!" << endl;
sam = ZERO;
sue = ZERO;
cout << "Same has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited." << endl;
cout << "Take $1 from each account." << endl << "Now";
sam = sam - 1;
sue = sue - 1;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited." << endl << "Lucky Sue!" << endl;
return 0;
}
程序输出:
Sam has 32767 dollars and Sue has 32767 dollars deposited.
Add $1 to each account.
Now Sam has -32768 dollars and Sue has 32768 dollars deposited.
Poor Sam!
Sam has o dollars and Sue has o dollars deposited.
Take $1 from each account.
Now Sam has -1 dollars and Sue has 65535 dollars deposited.
Lucky Sue!
意外的是,32767 加 1 却变成了 -32768?这是怎么回事?
这就是整形溢出
5.C++ 如何确定常量的数据类型
cout << "year = " << 2024 << "\n";
在这个程序中,常量 2024 被储存为了什么整形呢?
一般来说,C++ 会把常量储存为 int 类型。
我们可以在整数后面注明 L 来表示储存为 long,U 表示 unsigned int,ul 表示 unsigned long,同理,还有 ULL。(以上所述大小写均可)
三、共勉
本篇博客是自我学习笔记,如果后续能够有人能够从中汲取到知识和收获,这也是我所希望的。如果有读者不懂或有问题的话,欢迎提出来,让我们一起讨论。同时,我将继续更新 C++ 入门学习系列笔记,敬请期待。
谢谢!
标签:int,Day5,数据类型,long,C++,类型,内存 From: https://blog.csdn.net/linmohan0814/article/details/143134156