数组、字符串和指针

1.如何使用数组

  数组就是一组名为数组元素或简称元素的内存位置,各个内存位置可以存储相同数据类型的数据项,而我们可以用相同的变量名引用所有内存位置。

2.如何声明和初始化不同类型的数组

  声明数组:例如 long height[6];

  初始化数组:例如 int engine_size[5] = {200, 250, 300, 350, 400};

  C++11标准定义了一种表示一组初始值的新的统一方式,对于用这种方式初始化的所有对象,这些初始值都是相同的,包括标准模板库容器和数组。

  例如:int value[]{2,3,4}; 有了这种语法,=操作符就是不必要的。

3.如何对数组使用基于范围的for循环

  例如: double temperatures[] = {65.5, 68.0, 75.0, 77.5, 76.4, 73.8, 80.1};

      double sum = 0.0;

      int count = 0;

      for(double t : temperatures){

        sum += t;

        ++count;

      }

      double average = sum/count;

  还可以使用auto关键字来编写该循环:

    for(auto temperature : temperatures){

      sum += temperature;

      ++count;

    }

  auto关键字告诉编译器,需要确定包含数组当前值的本地变量的类型,编译器知道数组元素是double类型的,所以t也应是double类型。

  C++库提供了_countof()宏,只需要把数组名放在这个宏的括号中,就可以获得数组中的元素个数。

4.如何声明和使用多维数组

  例如:double beans[12][10];

  初始化例如: long data[2][4] = {

          {1, 2, 3, 5},

          {7, 11, 13, 17}

         };

        long data[2][4] = {0};

5.如何使用指针

  将间接寻址运算符*与某个指针一起使用,可以访问该指针指向的变量的内容。

6.如何声明和初始化不同类型的指针

  例如: int number(0);

      int* pNumber(&number);

      int * pNumber(nullptr);

  在nullptr添加到C++语言中之前,过去使用0或NULL(编译器用来代替0的宏)来初始化指针,当然它们现在仍然可以使用,但是,使用nullptr初始化指针要好的多。

  在C++语言中引入nullptr的原因是为了避免混淆作为整数值的字面值0和作为指针的0.字面值0的双重含义在有些情况下会产生问题。而nullptr是std::nullptr_t类型,不会与任何其他类型的值混淆。nullptr可以隐式转换为任何指针类型,但不能隐式转换为除bool类型以外的其他任何整数类型。

7.数组和指针之间的关系

  指向常量对象的指针:不能修改被指向的对象,但可以使指针指向其他对象。 如:const char* pstring("Some text");

  指向某个对象的常量指针:不能修改指针中存储的地址,但可以修改指针指向的对象。 如:char* const pstring("Some text");

  指向常量对象的常量指针:指针和被指向的对象都定义成常量,因此都不能修改。 如:const char* const pstring("Some text");

  一般来说,为了正确地解释更复杂的类型,只需要从右向左读它们。例如,类型const char*是一个指向字符的指针,且这些字符是const。类型char* const是一个指向字符的const指针。

  某些环境中,数组名称可以像指针一样使用。在大多数情况下,如果单独使用一维数组的名称,则该名称将自动转换为指向数组第一个元素的指针。注意,当数组名称用作sizeof操作符的操作数时,情况就不是这样。

  可以用指针执行算术操作。在算术方面,指针只能进行加、减运算,但还可以比较指针值,从而产生逻辑结果。指针算术隐式地认为指针指向某个数组,而算术运算是在指针包含的地址上进行的。

  指针算术运算产生的地址范围可以从数组第一个元素的地址到最后一个元素之后的第一个地址。如果超出该范围,则指针的行为是不确定的。这包括最后一个元素之后的第一个地址。

8.如何声明引用,关于使用引用的几点初步建议

  

  引用分为两种类型:lvalue引用和rvalue引用。实质上,引用是可用作其他对象的别名的一个名称。

  lvalue引用是另一个变量的别名,之所以称为lvalue引用是因为它引用的是一个可出现在赋值操作左边的持久存储位置。因为lvalue引用是别名而非指针,所以声明引用时必须指出对应的变量。与指针不同的是,我们不能修改引用,使其表示另一个变量。

  与lvalue引用一样,rvalue引用也可用作变量的别名,但它与lvalue引用的区别在于,它也能引用rvalue,这实质上是一个暂存的临时值。

  lvalue引用例子:

    long number(0L);

    long & rnumber(number);

    const int & refData = 5;

  C++中的每个表达式要么是lvalue要么是rvalue。变量是lvalue,是因为它表示一个内存位置,但rvalue不同,它表示计算表达式的结果。因此,rvalue引用是对有名称的变量的引用,并允许变量表示的内存内容可通过lvalue引用来访问。rvalue引用是对包含表达式结果的内存位置的引用。在类型名后面使用两个&&来指定一个rvalue引用类型。

  rvalue引用例子:

    int x(5);

    int&& rExpr = 2*x + 3;

    cout << rExpr << endl;

  这两种引用类型的主要应用是定义可能具有巨大值的函数。

数组:数组允许使用一个名称管理相同类型的多个变量。数组的每一维是在数组声明语句中数组名后面的方括号内定义的。

数组维数:数组每一维的索引值都是从0开始的。因此,一维数组中第5个元素的索引值是4。

初始化数组:在声明语句中将初始值放入大括号内,可以初始化数组。

基于范围的for循环:使用基于范围的for循环可以迭代数组中的每个元素。

指针:指针是包含另一个变量地址的变量。我们将指针声明为“指向某种类型的指针”,并且只能用给定类型的变量的地址给指针赋值。

指向const的指针和const指针:指针可以指向常量对象。这种情况下可以重新给指针赋值,使其指向另一个对象。指针也可以被定义成const,这种情况下指针不能被重新赋值。

引用:引用是另一个变量的别名,可以用来代替被引用的变量。引用必须在声明时初始化。我们不能通过给引用重新赋值,而使其指向另一个变量。

sizeof操作符:sizeof操作符返回其参数指定的对象占用的字节数,圆括号内的参数可以是变量或类型名称。

new操作符:new操作符动态分配空闲存储器中的内存。当根据请求成功分配内存之后,该操作符返回一个指向提供的内存区域头部的指针,如果因故不能分配内存,则默认抛出一个使程序终止的异常。

delete操作符:使用delete操作符可以释放前面用new操作符分配的内存。

原文地址:https://www.cnblogs.com/huojing/p/3601455.html