[C++Primer] 第二章 变量和基本类型

第二章 变量和基本类型

引用

  1. 引用定义的时候必须初始化。

  2. 引用初始化之后无法重新绑定到其它对象上。

  3. 引用本身并不是对象,所以没有指向引用的引用(不管如何多层引用,引用的还是源对象)

下面用一个简单的例子说明:

int a=1;
int& b=a;
cout<<&a;//00D4FE0C
cout<<&b;//00D4FE0C

可以看出对源对象a进行取地址和对b进行取地址的结果是一样的(实际上,引用的本质就是一个常量指针,即int * const ptr类型

指针

  1. 指针本身就是个对象,允许对指针本身进行复制和拷贝操作。
  2. 指针定义时可以不赋初值,也可以指向nullptr,同时,其值也可以为未确定的值。
  3. 指针在其生命周期内可以指向不同的对象。

下面用一个简单例子说明:

int a=1;
int& b=a;
cout<<&a;//012FFD64
cout<<&b;//012FFD58

可以看出指针本身的地址和源对象的地址是不一样的,这是指针和引用的一个重要区别。

nullptr和NULL

nullptr是C++ 11 引入的新的关键字,而NULL是一个值为0的预处理变量,即:

#define NULL 0

在程序中最好使用nullptr关键字而非NULL,例如下面的例子:

#include <iostream>void go(int num)
{std::cout << "number" << std::endl;
}void go(void *p)
{std::cout << "ptr" << std::endl;
}void main()
{void *p = NULL;go(p);//ptrgo(NULL);//number 得到的很有可能不是想要的答案go(nullptr);//ptrsystem("pause");
}

void*指针

void*是一种特殊的指针类型,可以存放任意对象的地址,但是我们不了解其中存放的对象到底是什么类型的,我们可以用此指针来保存对象,而void表明我们我们用什么类型来解释这段存储空间中的对象(包括对象的长度),但我们无法对这个对象进行操作,因此在进行对象操作之前我们需要先对该指针进行类型转换。

int a=1;
void* b=&a;
cout << *(int*)b << endl;// 1

const限定符

const关键字用来表示一个常量,例如:

const int a=100;

编译器会在编译过程中把所有用到这个变量的地方全部替换成常数100。

默认情况下,const对象仅仅在当前文件内有效,如果多个文件中出现了同名的const变量,那么等于在不同文件中分别定义了独立的变量。(如果需要多个文件之间共享,那么我们需要使用extern关键字)

  • const结合指针

通过下面的代码区分const结合指针的区别:

int a=10;
const int * ptr=&a;// ptr本身可以指向别的对象,但不能通过ptr修改a的值
int const * ptr=&a;// 同上
int * const ptr=&a;// ptr本身不能改变,但是可以通过ptr修改a的值

类型别名

  • typedef

我们可以使用typedef来定义类型别名,这样我们就可以把越写越长的变量类型用短的单词代替,例如:

typedef int in;//in就是int的别名
typedef in i,*ptr;//i就是int的别名,ptr是int*的别名
#include <iostream>
using namespace std;
class A
{
public :void test() { cout << 1; }
};
int main()
{auto i=new A();typedef void (A::*ptr)(); //ptr为指向A成员函数的指针类型,指向的函数的参数和返回值都为空ptr a= &A::test;(i->*a)();//输出1
}

同时我们需要注意typedef与define的一个重要区别:

typedef char* type;
#define def char*
type i1, i2;    // i1 和 i2 均为指向 char 的指针
def  j1, j2;   // j1 为指向 char 的指针, 但 j2 为char 型变量
  • using

C++11新标准提出了新的方法,使用using来取别名:

using newInt= int;
newInt a=10;

auto类型说明符

自动分析表达式类型。

auto i=1;//int类型
  • 一般会忽略顶层const,保留底层const

顶层const:指针本身是常量;

底层const:指针指的对象是常量;

int i=0;
int * const p1=&i;      //这是顶层const,不能改变p1的值
const int ci=42;        //顶层const,不能改变ci的值
const int *p2=&ci;      //底层const,不能改变p2的值
const tint * const p3=p2;//左边是底层const,右边是顶层const
const int & r=ci;       //用于声明引用的都是底层const

个人理解:定义的变量本身不能改变,则为顶层const,反之则为底层const(引用除外,引用都是底层const)

再看auto推断规则:

int i=1;
const int ci=i;
const int &cr=ci;
auto b=ci;//b是一个整数,顶层const忽略
auto c=cr;//c是一个整数,cr是ci别名,ci是顶层const
auto d=&i; //d是一个整型指针
auto e=&ci; //e是一个整型常量指针,对常量对象取地址是一种底层const,也就是const int* e=&ci;

再看一个例子:

int a=1;
const int* ptr1=&a;
auto res1=ptr1;//底层const保留,res1类型为const int*int* const ptr2=&a;
auto res2=ptr2;//顶层const忽略,res2类型为int*

如果希望推到出的auto类型是一个顶层const,那么需要明确指出:

const auto f=ci;//这时候才会带上const,f类型为const int

decltype

decltpye用于选择并返回操作数的数据类型,在这个过程中编译器分析表达式得到类型,但是不计算表达式实际的值。

decltype(function()) sum=x; //sum的类型就是function函数返回值的类型
  • decltype和auto的区别

decltype返回该变量的类型,包括顶层const和引用在内。

const int ci=0,&cj=ci;
decltype(ci) x=0;   // x的类型是const int
decltype(cj) y=x;   // y的类型是const int&,y绑定到变量x
decltype(cj) z;     // 错误,z是一个引用,必须初始化

需要指出,引用从来都是作为其所指对象的同义词出现,只有用在decltype处是个例外。

此外,对于decltype所用的表达式来说,多加了一对括号和不加括号时会有区别,如果给变量加上了一层或者多层的括号,那么编译器会把它当作一个表达式,变量时一种可以作为赋值语句左值的特殊表达式,所以这样的decltype会得到引用类型。

decltype((i)) d;    // 错误,d是int&,必须初始化
decltype(i) e;      // 正确,e是一个int

decltype((variable))的结果永远是引用,而decltype(variable)的结果只有在variable本身是一个引用时才是引用。

预处理器

C++程序可以使用#define指令把一个名称设定为预处理变量,用#ifdef表示在变量定义的时候为真,#ifndef为当变量未定义时为真,一旦检查结果为真,则执行后续操作到#endif为止。

#ifndef HEAD_H
#define HEAD_H... your code...#endif

注意在VS中也可以使用#pragma once来表示只编译一次,但是只在windows下生效,无法跨平台。

转载于:https://www.cnblogs.com/lizhenghao126/p/11052117.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362300.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VUE v-bind绑定class和style

1、绑定class &#xff08;1&#xff09;对象语法 <!DOCTYPE html><html lang"zh"><head><meta charset"UTF-8" /><title>vue示例</title></head><body><div id"app"><div class&quo…

js笔记(四)内置对象Math和Date()、浏览器对象模型BOM

大标题小标题备注一、内置对象Math、Date()1. Math 数学对象;2. Date() 日期对象;常用的数学对象&#xff1a;Math.PI、abs(n)、round(n)、random()、floor(n)、ceil(n)、pow(x,y)、sqrt(n)、min(3,4,5,6)、max()、sin(弧度)、cos()、tan()&#xff1b;获取日期&#xff1a;get…

ListView展示SIM信息

首先看一下程序运行后的图片&#xff1a; 在开始写代码之前&#xff0c;看展示下程序的结构&#xff1a; 下面开始代码, 第一步&#xff0c;主程序代码&#xff1a; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundl…

MQ

https://mp.weixin.qq.com/s/AFjYLtqGXkOVHcETePBHBw https://mp.weixin.qq.com/s/5pPjUOfAH6IN7cXMgMvoKw转载于:https://www.cnblogs.com/codeLei/p/11052781.html

代理的JavaOne 2014观察

我今年无法参加JavaOne&#xff0c;但很高兴看到一些在线资源涵盖了JavaOne 2014的活动。在本文中&#xff0c;我总结了JavaOne 2014的一些观察结果&#xff0c;并提供了指向提供这些观察结果的参考的链接。提供有关这些观察的更多背景细节。 列出的观察结果没有特定的顺序&…

push和unshift方法

push和unushift都是向数组插入元素。 push是向数组尾部插入元素。 unshift是向数组头部插入元素。 共同点&#xff1a;都可以一次插入多个元素。 arrayObject.push(newelement1,newelement2,....,newelementX) arrayObject.unshift(newelement1,newelement2,....,newelement…

js笔记(五)文档对象模型DOM

大标题小节一、DOM选择器1. id 选择器&#xff1a;getElementById("id名")&#xff1b;2. class 选择器&#xff1a;getElementByClassName("class名")&#xff1b;3. 标签选择器&#xff1a;getElementsByTagName("标签名")&#xff1b;4. name…

星期五基准功能Java

让我们的产品负责人想象一下有一天会发疯&#xff0c;并要求您执行以下操作&#xff1a; From a set of Strings as follows : “ marco_8”&#xff0c;“ john_33”&#xff0c;“ marco_1”&#xff0c;“ john_33”&#xff0c;“ thomas_5”&#xff0c;“ john_33”&am…

SEO优化实践操作

合理的title、description、keywords&#xff1a;搜索对着三项的权重逐个减小&#xff0c;title值强调重点即可&#xff0c;重要关键词出现不要超过2次&#xff0c;而且要靠前&#xff0c;不同页面title要有所不同&#xff1b;description把页面内容高度概括&#xff0c;长度合…

Flot画实时曲线

源代码&#xff1a; <head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /> <title>深海的小鱼编制-PLOT</title> <script language"javascript" type"text/javascript" src"…

RHQ指标的WildFly子系统

对于RHQ-Metrics&#xff0c;我已经开始为WildFly 8编写一个子系统&#xff0c;该子系统能够在WildFly内收集指标&#xff0c;然后以固定的时间间隔&#xff08;当前为每分钟&#xff09;将其发送到RHQ-Metrics服务器。 下一张图是该发件人连续运行1.5天时结果的可视化效果的G…

Linux下实现客户端和服务器端的通信

首先&#xff0c;可以将代码复制下来放到U盘里&#xff0c;然后挂载到Linux上 挂载步骤 找到设备->USB->你U盘的名字 挂载成功 访问U盘把代码拷贝到home文件夹下&#xff0c;就可以直接进行编译。 client.c #include <stdio.h> #include <unistd.h>#include…

gvim 安装 taglist

gvim 安装 taglist windows XP下&#xff0c;gvim,安装taglisttaglist 是在vim 下可以像 vc当中的可以列出类&#xff0c;函数 的插件。一&#xff0c;下载ctags,将其中的 ctags.exe 复制到gvim.exe 所在的目录&#xff0c;我的是 C:\Program Files\Vim\vim73如果不复制的话&am…

js笔记(八)ES6

大标题补充描述一、 ES6 中新增的声明方式&#xff1a;let、constvar、let、const之间的区别二、 ES6 字符串扩展1. 子串的识别&#xff1a;includes()、startsWith()、endsWith()&#xff1b;2. 重复字符串&#xff1a;repeat()&#xff1b;3. 字符串补全&#xff1a;padStart…

卡夫卡编年史队列基准

总览 最近&#xff0c;我被要求比较《卡夫卡》和《编年史》的性能。 没有两个产品是完全一样的&#xff0c;要进行公平的比较并不容易。 我们可以尝试运行类似的测试&#xff0c;看看会得到什么结果。 该测试基于Apache Kafka性能结果 。 测试使用了什么&#xff1f; 卡夫卡测…

webpack css打包为一个css

1、安装 npm install extract-text-webpack-plugin --save-dev 2、项目目录&#xff1a; index文件夹下的index.css&#xff1a; body{background-color: #ccc;}.flex-div{display: flex;} index文件夹下的index2.css&#xff1a; p{text-indent: 2em;} index文件夹下的index-l…

javascript深入理解js闭包

闭包&#xff08;closure&#xff09;是Javascript语言的一个难点&#xff0c;也是它的特色&#xff0c;很多高级应用都要依靠闭包实现。 一、变量的作用域 要理解闭包&#xff0c;首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两种&#xff1a;全局变量和局…

Codeforces Round #568 (Div. 2) G2. Playlist for Polycarp (hard version)

因为不会打公式&#xff0c;随意就先将就一下&#xff1f; #include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<vector> using namespace std; typedef long long LL; const int N55; const int MOD1e97; int…

新的开始 和一些总结

接触编程不久&#xff0c;2年而已&#xff0c;也不精通&#xff0c;看得比较泛。java&#xff0c;C&#xff0c;C#都有所涉猎&#xff0c;但是仅仅停留于可以编码的阶段&#xff0c;让我就某个问题给出专业的解释&#xff0c;是断无可能的。现在准备考研了&#xff0c;很长一段…

jQuery实现页面关键词高亮

示例代码&#xff0c;关键位置做了注释&#xff0c;请查看代码&#xff1a; <html><head><title>jQuery实现页面关键词高亮</title><style type"text/css">* {margin: 0;padding: 0;}p {padding: 10px;margin-bottom: 20px;}.highligh…