c++ Primer 数据类型(三、四)

目录

基础类型

float:

double:

long: 

bit: 

wchar_t: 

c++11新增的类型:

复合类型

数组:

一维数组:

二维数组:

c风格字符串:

c++风格字符串:

结构体:

共用体(union):

匿名共用体:

枚举:

指针:

引用:

字符串输入(cin):

如何确定常量类型?

什么时候创建临时变量?

什么是左值,什么是右边值?


基础类型

float:

     4字节,6位有效数字

double:

    8字节,15位有效数字

long: 

    在x86下占4字节,x64占8字节(long int)

bit: 

     1字节占8位

wchar_t: 

 扩展字符集,类型是一种整数类型,它有足够的空间,可以表示系统使用的最大扩展字符集,对底层的选择取决于实现,随实现而异,可通过加上前缀L来指定宽字符常量

c++11新增的类型:

char16_t和char32_t:用于有特定长度和符号特征的类型,两者都是无符号的,分别为16位和32位,前者使用u表示,后置U表示(也是内置的整型,随系统而异)

复合类型

数组:

不能将一个数组赋给另一个数组

一维数组:

CODE:

#include <iostream>
using namespace std;

void test(const int* begin, const int* end)
{
	const int* temp = nullptr;
	// 当temp = end时, 它指向的是最后一个元素的后面那个元素
	for (temp = begin; temp != end; temp++)		
	{
		cout << *temp << endl;
	}
}

int main()
{
	int data[] = { 1,2,3,4,5 };
	test(data, data+3);
	return 0;
}

二维数组:

        指针数组:

char *arr[4] = {"hello", "world", "hefei", "coliy"};

指针数组可以说成是”指针的数组”,首先这个变量是一个数组,其次,”指针”修饰这个数组,意思是说这个数组的所有元素都是指针类型,在32位系统中,指针占四个字节。

        数组指针:

char (*pa)[4];

数组指针可以说成是”数组的指针”,首先这个变量是一个指针,其次,”数组”修饰这个指针,意思是说这个指针存放着一个数组的首地址,或者说这个指针指向一个数组的首地址。

CODE:

#include <iostream>
using namespace std;

void test(const int arr[][3], int size)
{
	const int* temp = nullptr;
	for (int i = 0; i < (size / 3); ++i)
	{
		for (int j = 0; j < 3; j++)
		{
			cout << *(arr[i] + j) << endl;
		}
	}
}

int main()
{
	int arr[][3] = {						// 第一个综括号里面的参数可以省略
		{1, 2, 3},
		{4, 5, 6},
		{7, 8, 9}
	};
	test(arr, sizeof(arr) / sizeof(int));
	return 0;
}

c风格字符串:

1.以空字符'\0'结尾,以字符数组形式存在

2.字符串常量(使用双引号)不能与字符常量(使用单引号)互换,字符是整型的另一种写法

3.cout输出字符串是逐个处理字符串中的字符,直到到达空字符为止

4.可以将一个char* 的字符串赋给string,反过来不行

sizeof()求所占字节,strlen()计算可见字符长度

c++风格字符串:

strcpy()将字符串复制到字符数组

strcat()将字符串附加到字符数组的尾部

结构体:

可以使用赋值运算符(=)将结构赋给另一个同类型的结构

结构体位字段:

用处:用于很宝贵的存储空间

潜在问题:不可移植的风险

共用体(union):

只能能使存储其中的一种类型,可节省空间

union DATA
{
    int a;
    double b;
};

int main()
{
    DATA data;
    data.a = 1;
    cout << "a = " << data.a << endl;   // 1
    cout << "b = " << data.b << endl;   // b = -9.25596e+61

匿名共用体:

没有名称:只有一个成员是当前的成员,他们的地址相同

typedef struct INFO
{
    union
    {
        int a;
        double b;
    };
};

int main()
{
    INFO data;
    data.a = 1;
    cout << "a = " << data.a << endl;   // 1
    cout << "b = " << data.b << endl;   // 1

枚举:

不能将int转换为枚举的变量,除非强制类型转换

枚举可以转换为int类型

枚举的取值范围:根据枚举的类型决定,比如int就是int的取值范围(书上:例如:(-6, 101) -> 范围(-7,127))->个人认为错误,或许版本问题

指针:

指针是一个变量,存储的是值的地址,而不是值本身

数组指针:int(*p)[20]:指向包含20个元素的int数组

指针数组:int* p[20]:包含20个元素

new分配的内存称之为动态联编,使用delete释放

数组的字符串、用引号括起的字符串常量以及指针所描述的字符串,处理的方式一样,都将传递他们的地址

字符数组赋值给一个char* 类型的字符串,字符数组要加一,因为后面有一个字符串结束符

指针的用法和危害后续补充

如何使用指针?

指针比引用更为灵活,但是其风险也很大。使用指针时一定要检查指针是否为空(NULL),且空间回收后指针最好置零,以免野指针的发生造成内存泄漏等问题

引用:

引用是已定义变量的别名

(一)、一个变量可取多个别名

(二)、引用必须初始化,指向有效的变量

(三)、引用只能在定义时被初始化一次,之后不可变 ,相当于(Type * const var)

(四)、引用在定义上是说引用不占据任何内存空间,但是编译器在一般将其实现为const指针,即指向位置不可变的指针,所以引用实际上与一般指针同样占用内存

(五)、,不要返回一个临时变量的引用

(六)、如果实参与引用参数不匹配,C++将生成临时变量,。当前,仅当参数为const引用时,C++才允许这样做

sizeof指针对象和引用对象的意义不一样。sizeof引用得到的是所指向的变量的大小,而sizeof指针是对象地址的大小。

long long a = 5;

long long* c = &a;
long long &b = a;

x86: sizeof(b) = 8字节        sizeof(c) = 4字节

#include <iostream>
using namespace std;

int main(void)
{
	int a = 0;
	int &b = a;
	cout << "a" << &a << endl;	//a0096FCF8
	cout << "b" << &b << endl;	//a0096FCF8
	return cin.get();
}

字符串输入(cin):

cin 使用空白(空格、制表符、换行符)来确定字符串的结束位置

cin 不再读取被丢弃的换行符

getline()读完丢弃换行符(通过换行符确定结尾)

例如:参数10.则函数最多读9个, 余下的空间用于存储自动在结尾处添加的空自符('\0')

        get() 换行符保留(保留在输入序列中), 但 get() 不再读取被丢弃的换行符

如何确定常量类型?

2022ul:代表unsigned long类型

2022f:代表float类型

什么时候创建临时变量?

(一)、实参的类型正确, 但不是左值

(二)、实参的类型不正确, 但可以转换为正确的类型

#include <iostream>
using namespace std;

double refcube(const double& ra)
{
	return ra*ra*ra;
}


int main(void)
{
	double side = 3.0;

	double* pd = &side;

	double& rd = side;

	long edge = 5L;

	double lens[4] = { 2.3,3.4,4.5,6.7 };

	double c1 = refcube(side);			// ra 是side

	double c2 = refcube(lens[2]);		// ra是lens[2]

	double c3 = refcube(rd);			// ra 是 rd

	double c4 = refcube(*pd);			// ra 是*pd

	double c5 = refcube(edge);			// ra 是临时变量 -> 实参类型不正确, 但可以转换为正确的类型

	double c6 = refcube(7.0);			// ra 是临时变量 -> 实参的类型正确, 但不是左值

	double c7 = refcube(side + 10.0);	// ra 是临时变量 -> 实参的类型正确, 但不是左值

	return cin.get();
}

什么是左值,什么是右边值?

左值:

它是一个占确定内存的对象(地址), 左值参数是可被引用的对象。

例如: 变量,、数组元素、结构成员、引用、解引都是左值

可修改的左值: 加const关键字

右值:

不在内存占有确定位置的表达式。

例如: 字面常量 (双引号括起的字符串除外, 因为他们由地址表示)、包含多项的表达式

右值一定不能转换成左值。

左值和右值的互换:

二元加运算符 ‘+’ 要求两个右值作为它的参数并且返回一个右值

int a = 1;             //a是一个左值
int b = 2;             //b是一个左值
int c = a + b;       //+需要右值,所以a和b都转换成右值,并且返回一个右值

学习笔记,个人理解创作,后续会添加,现在只是略写条目.....

注:如有错误,及时跟进Thanks♪(・ω・)ノ

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值