C++ Primer学习笔记与思考_1----变量和基本类型

C++ Primer学习笔记与思考_1----变量和基本类型

类型有什么作用?

类型告诉我们数据代表什么意思以及可以对数据执行哪些操作。

一:基本内置类型

C++标准规定了每个算术类型的最小存储空间,但是它并不阻止编译器使用更大的存储空间。对于int,几乎所有的编译器使用的存储空间都比所要求的大。

字符类型有两种char和wchar_t,其中wchar_t用于扩展字符集,比如汉字和日文,这些字符集中的一些字符不能用单个的char表示。

 c++ primer第32页

     和其他类型不同,char有三种不同的类型:普通char、unsigned char、signed char。虽然char有三种不同的类型,但是只有两种表示方式。可以使用unsigned char或者signed char表示char类型。使用哪种char类型标识方式由编译器决定。

关于这段话的理解:为什么有三种不同的类型,又为什么有两种表示方式?

原来是这样的:在程序中直接写个int , 默认是signed int , 但是在程序中写个char ,就没有默认了,具体是signed char 还是unsigned char ,取决于编译器的设置。

对于vc、x86上的gcc,char被处理成signed char。 如果想测试你的编译器,可以用这段代码

char a =-1;

printf("a=%d",a);

如果结果是 -1,则当前编译器将char 处理成signed char; 如果结果是255,则当前编译器将char处理成unsigned char。

整型的赋值问题

当我们试着把一个超出其取值范围的值赋给一个指定类型的对象时,结果如何?

(1)  对于unsigned类型来说,编译器会对其取模然后得到结果。试图将 336 存储到 8 位的 unsigned char 中,则实际赋值为 80,因为 80 是 336 对 256 求模后的值。此外,负数总是超出unsigned的范围,在c++中把负数赋给unsigned是完全合法的。如果将-1赋给8位的unsigned char,那么结果是255,因为255是-1对256求模后的值。

(2)  当将超过取值范围的值赋给 signed 类型时,由编译器决定实际赋的值。在实际操作中,很多的编译器处理 signed 类型的方式和 unsigned 类型类似。也就是说,赋值时是取该值对该类型取值数目求模后的值。然而我们不能保证编译器都会这样处理 signed 类型。

二:字面值常量

转义字符的一种使用方式:

<span style="color:#330033;"><span style="font-family:SimSun;">#include<iostream>
using namespace std;
int main()
{
	//输出 Welcome to the "acm" world,必须使用转义字符
	cout<<"Welcome to  the \"acm\" world"<<endl;
	return 0;
}</span></span>

字符串字面值:

<span style="color:#330033;"><span style="font-family:SimSun;">#include<iostream>
using namespace std;
int main()
{
	cout<<"a multi-line"//正确,类型一致
	      "string literal"
		  <<endl;

  // cout<<"multi-line " L"literal"<<endl; //错误,字符串字面值和宽字符串字面值类型不同

  cout<<"a mul-line   using a namespace "<<endl;//多面字符串使用\,此后不得加注释和空格
}</span></span>

三:变量

1.关键字不能是变量名

2.一般用小写字母并且要有助于记忆

3.多个词的标识符在之间加下划线如:student_loan

C++的初始化和赋值是两种不同的操作,这对于内置类型可能没什么区别,但是对于类类型的区别很明显。初始化是指创建变量并给他赋初始值,而赋值则是擦除对象的当前值并用新的值代替。

1) 变量初始化规则

1. 内置类型的变量是否初始化取决于变量定义的位置:在函数体外定义的变量都初始化成0,在函数体内定义的内置类型变量不进行自动初始化。

【但是,未初始化的变量事实上都有一个值】

建议:每个内置类型的对象都要初始化。

2. 类通过定义一个或多个构造函数来控制类对象的初始化。如果一个类有默认构造函数,则无论变量在哪儿定义,默认构造函数都会被调用。

2) 声明和定义

C++通过extern关键字声明,向程序表明变量的类型和名字。因为extern是声明,所以不分配存储空间。

一个变量可以声明多次,但只能定义一次

如果声明有初始化式,那么它可以被当作是定义,即使有声明标记extern,如:

<span style="color:#330033;"><span style="font-family:SimSun;">extern int i;//只声明没有定义
int i; //定义变量
extern double PI = 3.14;  //只有当extern声明位于函数外部时,才可以含有初始化式,但是有些编译器还是不能通过编译。
</span></span>

3)名字的作用域

c++的作用域可以嵌套,已花括号为界

<span style="color:#330033;"><span style="font-family:SimSun;">//在函数内定义一个与函数可能会用到的全局变量同名的局部变量总是不好的,局部变量最好使用不同的名字!
#include <iostream>
#include <string>
using namespace std;
string s1 = "hello";  // s1 has global scope   

int main()
{
    string s2 = "world"; // s2 has local scope   

    // uses global s1; prints ``hello world''
    cout << s1 << " " << s2 << std::endl;     

    //int类型的s1将屏蔽掉std::string类型的s1
    int s1 = 42; // s1 is local and hides global s1   

    // uses local s1; prints ``42 world''
    cout << s1 << " " <<  s2 << std::endl;
    return 0;
}  </span></span>

英语时刻:Destiny is not a matter of chance .It‘s a matter of choice.(命运不在于机会,而在于选择。)

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-24 05:07:38

C++ Primer学习笔记与思考_1----变量和基本类型的相关文章

C++ Primer 学习笔记_102_特殊工具与技术 --运行时类型识别[续]

特殊工具与技术 --运行时类型识别[续] 三.RTTI的使用 当比较两个派生类对象的时候,我们希望比较可能特定于派生类的数据成员.如果形参是基类引用,就只能比较基类中出现的成员,我们不能访问在派生类中但不在基类中出现的成员. 因此我们可以使用RTTI,在试图比较不同类型的对象时返回假(false). 我们将定义单个相等操作符.每个类定义一个虚函数 equal,该函数首先将操作数强制转换为正确的类型.如果转换成功,就进行真正的比较:如果转换失败,equal 操作就返回 false. 1.类层次 c

C++ Primer学习总结 第1-2章 变量和基本类型

第1-2章 变量和基本类型 1.下面这个语句在C++98和C++11中的输出结果不同. C++98结果: (如果想要更高的精度,可以用%.9lf,输出9位有效数字) C++11结果: 结论: printf的%lf在C++11中表示longdouble,所以用中%f就可以输出float和double类型.而printf在C++98中可以用%lf正确输出double. 如果是scanf的话,不论C++98还是C++11中float都用%f读取,double都用%lf读取,因为二者结构不同.   2.

C++ Primer 学习笔记与思考_7 void和void*指针的使用方法

(一)void的含义 void的字面意思是"无类型",void差点儿仅仅有"凝视"和限制程序的作用,由于从来没有人会定义一个void变量,让我们试着来定义: void a; 这行语句编译时会出错.提示"illegal use of type 'void'".只是.即使void a的编译不会出错.它也没有不论什么实际意义. void真正发挥的作用在于: (1) 对函数返回的限定: (2) 对函数參数的限定. int f(void); equal t

C++ Primer 学习笔记与思考_9 表达式中过的那些容易忽略的地方

(一)移位操作符用于IO 输入输出标准库分别重载了位操作符>>和<<用于输入和输出.并且像其他的二元操作符一样,移位操作符也是左结合的,这也正好说明了我们为什么可以把多个输入输出操作连接为单个语句: cout<<"hi"<<"there "<<endl; 将其执行为: ( (cout<<"hi")<<"there" )<<endl;

C++ Primer 学习笔记与思考_4 ---getline&amp;&amp;size_type&amp;&amp;const_iterator混搭

(一)getline的用法 我们在使用string读入字符串的时候,其输入操作符: * 读取并忽略开头所有空白字符(如空格,换行符,制表符) * 读取字符直至再次遇到空白字符,读取终止. 所以如果我们输入"hello world",string将只输出hello. 为了解决这个问题,我们引入getline函数,它接受两个参数:一个输入流对象和一个string对象,但是getline会读取换行符,保存到string中时却忽略换行符,所以string中是空串. 我们通常用getchar()

C++ Primer 学习笔记与思考_3 ---头文件那些事儿(extern)

(一)extern在头文件里的使用方法 由于头文件包括在多个源文件里.而且变量的定义仅仅能出现一次,所以在头文件里. 仅仅能够声明不能够出现定义. 我们能够在头文件里用extern声明全局变量,这样在包括此头文件的cpp 中可直接使用 声明过的这个全局变量(例如以下面程序中的变量a). 可是有三个例外: 1.头文件里能够定义类 2.值在编译时就已经知道的const对象 3.能够定义inline函数 extern int ival; // yes extern int ival=1; //erro

C++ Primer 学习笔记与思考_10 类型转换易错处大总结

(一)隐式转换 先来看一组样例: int ival=0; ival=3.451+3; 首先做加法操作,操作数分别为int和double类型,c++并没有直接把两个数加在一起,而是提供了一组转换规则,以便在执行算术操作之前,将两个操作数转换为同一种数据类型.在这里是自动执行的,所以他们被成为隐式转换. 因为 C++定义了算术类型之间的内置转换以尽可能防止精度损失,所以这里3转换为double型相加得6.451.但是下一步赋值的时候,右操作数进行截断处理,对此精度会有损失,编译器也会给出警告. 2.

C++ Primer 学习笔记与思考_7 void和void*指针的用法

(一)void的含义 void的字面意思是"无类型",void几乎只有"注释"和限制程序的作用,因为从来没有人会定义一个void变量,让我们试着来定义: void a; 这行语句编译时会出错,提示"illegal use of type 'void'".不过,即使void a的编译不会出错,它也没有任何实际意义. void真正发挥的作用在于: (1) 对函数返回的限定: (2) 对函数参数的限定. int f(void); equal to in

C++ Primer 学习笔记与思考_5 数组和动态数组易错点解读

1. 数组的定义 数组定义中的类型名可以是内置数据类型或者类类型:除了引用之外,数组元素的类型还可以是任意的复合类型.另外,非const变量以及要到运行阶段才知道其值的const变量都不能用于定义数组的维数. #include <iostream> #include <string> #include <cstring> #include <bitset> using namespace std; int main() { const int MAXN1 =