现代C++程序应尽量使用vector和迭代器类型,而避免使用低级的数组和指针。

设计良好的程序只有在强调速度时才在类实现的内部实现数组和指针。
 
更多地使用vector来取代数组,数组被严格限制于程序内部使用。
 
int staff = 27只有在运行时才能获得它的值
 
char ca1[] = {'C',  '+'  , '+'};           // no  null  维数3
char ca2[] = {'C' , '+' , ' + ',  '\0'}    // explicit null   维数4
char ca3[] = "C++"                  维数四  // null terminator added automatically
 
不允许数组直接复制和赋值
 
数组下标的正确类型是size_t
 
vector的遍历可使用下标或迭代器实现,同理,
也可用下标或指针(pointer)来遍历数组。
 
指针是指向某种类型对象的复合数据类型,是用于数组的迭代器:指向数组中的一个元素。
指针用于指向对象。
 
与迭代器一样,指针提供对其所指对象的间接访问,只是指针结构更通用一些。
与迭代器不同的是,指针用于指向单个对象,而迭代器只能用于访问容器内的元素。
 
指针保存的是另一个对象的地址
 
&取地址(address-of)操作符
 
2.3.1左值:左值可以出现在赋值语句的左边或右边
        右值:右值只能出现在赋值的右边,不能出现在赋值语句的左边
 
有效的指针
1.保存一个特定对象的地址
2.指向某个对象后面的另一个对象
3.0值。若指针保存0值,表明它不指向任何对象。
 
很多运行时错误都源于使用了未初始化的指针
 
建议程序员在使用之前初始化所有的变量,尤其是指针。
 
C++把指针初始化为NULL等效于(==)初始化为0值  C
 
把int型变量赋给指针是非法的,尽管此int型变量的值可能为0
 
void*指针 可以保存任何类型对象的地址
 
指针提供间接操纵其所指对象的功能。与迭代器进行解引用操作一样。
对指针进行解引用课访问它所指的对象,*操作符(解引用操作符)将获取指针所指的对象
 
给指针赋值和通过指针进行赋值
*sp1 = "a new value";
sp1 = sp2;
 
指针和引用的比较
都可间接访问另一个值
区别1.引用总是指向某个对象:定义引用时没有初始化是错误的
       2.赋值行为的差异:给引用赋值修改的是该引用所关联的对象的值
          而并不是使引用与另一个对象关联。引用一经初始化,就始终指向同一个特定对象(这就是为什么引用必须在定义时初始化的原因)
 
C++使用**操作符指派一个指针指向另一个指针。
int ival = 1024;
int *pi = &ival;             // pi points to an int
int **ppi = π           //  ppi points to a pointer to int
ival = *pi = **ppi
pi = *ppi
 
C++语言中,指针和数组密切相关。特别是在表达式中使用数组名时,该名字会自动转换为指向数组第一个元素的指针:
int ia[] = {0,2,4,6,8};
int *ip = ia;          // ip points to ia[0]
 
 
两个指针减法操作的结果是标准库类型(library type)ptrdiff_t的数据。
与size_t类型一样,ptrdiff_t也是一种与机器相关的类型,在cstddef头文件中定义。size_t是unsigned类型,而ptrdiff_t则是signed整型。
 
允许在指针上加减0.
 
*解引用的操作符的优先级比加法操作符高
 
int *p = &ia[2];
int j = p[1];   // p[1] equivalent to *(p + 1)
                        p[1] is the same element as ia[3]
int k  = p[-2]; // p[-2] is the same element as ia[0]
 
C++允许计算数组或对象的超出末端的地址,但不允许对此地址进行解引用操作
 
内置数组类型具有标准库容器的许多性质,与数组联合使用的指针本身就是迭代器。
 
 
指向const对象的指针(常用作函数的形参)
不允许用指针来改变其所指的const值
C++语言强制要求指向const对象的指针也必须具有const特性
const double *cptr;  // cptr may point to a double that is const 
cptr是一个指向double类型const对象的指针。
cptr本身并不是const。定义时不需要对它进行初始化
 
不能使用void*指针保存const对象的地址,而必须使用const void*类型的指针保存const对象的地址。
 
允许把非const对象的地址赋给指向const对象的指针
 
cptr一经定义,就不允许修改其所指对象的值。可用其他方法修改其所指的对象
 
不能保证指向const的指针所指对象的值一定不可修改
 
const指针定义时初始化
本身的值不能修改
int errNumb = 0;
int *const curErr = &errNumb; // curErr is a constant pointer
curErr是指向int型对象的const指针
不能使curErr指向其他对象
 
指向const对象的const指针
const double pi = 3.14159;
// pi_ptr is const and points to a const object
const double *const pi_ptr = π
既不能修改pi_ptr所指向对象的值,也不允许修改该指针的指向(即pi_ptr中存放的地址值)。
pi_ptr首先是一个const指针,指向double类型的const对象
 
指针和typedef
p112
 
字符串字面值的类型就是const char类型的数组
以空字符null结束的字符数组
 
C++语言通过(const)char*类型的指针来操纵C风格字符串
 
cstring这些标准库函数不会检查其字符串参数
 
strlen(s)返回s的长度,不包括字符串结束符null。若不是null结束,则值不确定
strcmp(s1,s2) strcat(s1,s2)strcpy(s1,s2)
 strncat(s1,s2,n) strncpy(s1,s2,n) 更安全
 
if(cp1 < cp2) // compare addresses,not the values pointed to
比较在cp1和cp2中存放的地址
 
char largeStr[16 + 18 + 2]; // to hold cp1 a space and cp2
strncpy(largeStr , cp1, 17); // size to copy includes the null    16+ null
strncat(largeStr ," ",2);       // pedantic,but a good habit     null---> " null"
strncat(largeStr, cp2, 19);  //  adds at most 18 characters,plus a null  
C风格字符串尽量避免使用
 
尽可能使用标准库类型string
string largeStr = cp1;  
largeStr += " ";
largeStr += cp2;
标准库负责处理所有的内存管理问题
 
 
创建动态数组
每一个程序在执行时都占用一块可用的内存空间,用于存放动态分配的对象,此内存空间成为程序的自由存储区(free store)或堆(heap)
C++使用newdelete表达式在自由存储区中分配存储空间
 
int *pia = new int[10];  // array of 10 uninitialized ints
分配了一个含有10个int型元素的数组,并返回指向该数组第一个元素的指针,此返回值初始化了指针pia
在自由存储区中创建的数组对象是没有名字的,程序员只能通过其地址间接地访问堆中的对象
 
动态分配数组时,其元素只能初始化为元素类型的默认值。如果数组元素具有类类型,将使用该类的默认构造函数实现初始化;如果数组元素是内置类型,则无初始化
int *pia = new int[10];  // array of 10 uninitialized ints 无初始化
int *pia2 = new int[10]();   // array of 10 uninitialized ints 数组元素做值初始化  值为0
 
const对象的动态数组必须初始化  
已创建的常量元素不允许修改----因此这样的数组实际上用处不大
// error : uninitialized const array
const int *pci_bad = new const int[100];
// ok: value-initialized const array
const int *pci_ok = new const int[100]();
 
允许动态分配空数组
调用new动态创建长度为0的数组是合法的
char arr[0];                // error:cannot define zero-length array
char *cp = new char[0]; // ok : but cp can't be dereferenced
new返回有效的非零指针。不能进行解引用操作,因为没有指向任何元素
允许比较运算,指针加(减)0
 
cp没有指向任何对象,数组是空的
 
程序员必须显式地将其占用的存储空间返还给程序的自由存储区。
delete []pia;     // 遗漏了[],编译器无法发现,程序将在运行时出错
回收了pia所指向的数组,把相应的内存返还给自由存储区
 
p121
const char *str = st2.c_str();// ok.。。。。。。。。。。。。。。。。。。
 
允许使用数组初始化vector对象
const size_t arr_size = 6;
int int_arr[arr_size] = {0 , 1 ,2 ,3 ,4 ,5 };
// ivec has 6 elements:each a copy of the corresponding element in int_arr
vector<int> ivec(int_arr,int_arr + arr_size);
 
也可以是数组的子集
vector<int> ive(int_arr+1,int_arr+4);
 
多维数组数组的数组
 
int ia[3][4];
int (*ip)[4] = ia;       // ip points to an array of 4 ints
ip = &ia[2];              // ia[2] is an array of 4 ints 
*ip是int[4]类型-----即ip是指向含有4个元素的数组的指针
 
int *ip[4];       // array of pointers to int
int (*ip)[4];     // pointer to an array of 4 ints
 
用typedef简化指向多维数组的指针   p124
typedef int int_array[4];
int_array *ip = ia;
 
 
const size_t rowSize = 3;
     const size_t colSize = 4;
     int ia[rowSize][colSize];
    
     for(size_t i = 0 ; i != rowSize ; i++)
     {
          for(size_t j = 0 ; j != colSize ; j++)
          {
               ia[i][j] = i * colSize + j;
               cout << ia[i][j] << " ";
          }
          cout << endl;
     }
     ============================
     typedef int int_array[4];
     int_array *ip = ia;
    
     for(int_array *p = ia ; p != ia + 3 ; ++p)
     {
          for(int *q = *p;q != *p + 4 ; ++q)
          {
               cout << *q << " ";
          }
          cout << endl;
     }
 
vector 类型所包含的元素通过迭代器来操纵,
类似的,指针则用于访问数组元素。
现代C++程序不应使用C风格字符串
 
typedef研究。。。。

c++ primer 笔记 (四)的更多相关文章

  1. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  2. 《MFC游戏开发》笔记四 键盘响应和鼠标响应:让人物动起来

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9327377 作者:七十一雾央 新浪微博:http:// ...

  3. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  4. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  5. Java学习笔记四---打包成双击可运行的jar文件

    写笔记四前的脑回路是这样的: 前面的学习笔记二,提到3个环境变量,其中java_home好理解,就是jdk安装路径:classpath指向类文件的搜索路径:path指向可执行程序的搜索路径.这里的类文 ...

  6. Java加密与解密笔记(四) 高级应用

    术语列表: CA:证书颁发认证机构(Certificate Authority) PEM:隐私增强邮件(Privacy Enhanced Mail),是OpenSSL使用的一种密钥文件. PKI:公钥 ...

  7. Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  8. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. Django开发笔记四

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.邮箱激活 users app下,models.py: ...

  10. ES6学习笔记<四> default、rest、Multi-line Strings

    default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...

随机推荐

  1. linux系统--磁盘管理命令(二)

    一.硬盘的分区模式 之前的硬盘分区模式为MBR 主分区不超过4个 单个分区容量最大为2TB 前面的分区模式就为MBR分区模式. 另一种分区模式为GPT 主分区个数限制:在GPT的分区表中最多可以支持1 ...

  2. APR欺骗

    ARP欺骗简介 ARP欺骗是一种在局域网中常用的攻击手段,目的是让局域网中指定的(或全部)的目标机器的数据包都通过攻击者主机进行转发,是实现中间人攻击的常用手段,从而实现数据监听.篡改.重放.钓鱼等攻 ...

  3. dijkstra补充

    dijkstra主要写法: priority_queue<pair<int,int> >q; //大根堆 //dis第一维为dis的相反数 void dijkstra(){ m ...

  4. Nginx 内核优化

    内核参数的优化示例: /etc/sysctl.conf net.ipv4.tcp_max_tw_buckets = // timewait的数量,默认是180000. net.ipv4.ip_loca ...

  5. slice() 和splice()

    splice() 方法与 slice() 方法的作用是不同的,splice() 方法会直接对数组进行修改. 1, splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目. splice ...

  6. CF101D Castle

    传送门 首先,一定要把所有点遍历一遍,这时答案应该是\(\frac{\sum 某个点第一次被遍历的时间点}{n-1}\quad\),而且每条边只能走两次,所以每次要遍历完某棵子树才能遍历其它子树. 考 ...

  7. Linux 流量控制总结(TC)

    TC对带宽的描述:    mbps = 1024 kbps = 1024 * 1024 bps => byte/s    mbit = 1024 kbit => kilo bit/s.   ...

  8. Javascript定义变量

    在JavaScript中通过var来定义变量,不管是数字还是字符串,都可以通过这种方式来定义:我们既可以在声明变量的同时给变量赋值,也可以先声明变量,再给变量赋值. <script> va ...

  9. tidb 架构 ~Tidb学习系列(4)

    一 简介:今天我们继续学习tidb 二 集群管理 0 集群配置       验证 4台一组 3个kv 一个pd+server       上线 6台一组   1 动态添加kv服务       nohu ...

  10. 列式数据库~clickhouse 底层存储原理

    简介:今天介绍列式数据库的一些基本原理 一  数据目录 Data目录 数据存储目录,数据按照part分成多个文件夹,每个文件夹下存储相应数据和对应的元信息文件 Metadata 表定义语句,存储所有表 ...