c++基础复习之数组与指针

来源:互联网 发布:鬼吹灯故事解析 知乎 编辑:程序博客网 时间:2024/06/07 06:03

数组

定义: 数组是由类型名、标识符和维数组成的复合数据类型,类型名规定了存放在数组中的元素的类型,而维数则指定数组中包含的元素个数。
1. 如果没有显示提供元素初值,则数组元素会像普通变量一样初始化
- 在函数体外定义的内置数组,其元素均初始化为0;
- 在函数体内定义的内置数组,其元素无初始化;
- 不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显示初始化。

  1. 与vector类型相比,数组的显著缺陷在于:数组的长度是固定的,而且程序员无法知道一个给定数组的长度。数组没有获取其容量大小的size操作,也不提供push_back操作在其中自动添加元素。如果需要更改数组的长度,程序员只能创建一个更大的新数组,然后把原数组的所有元素复制到新数组空间中去。

习题(c 风格字符串)

  1. 编写必要的代码将一个数组赋值给另一个数组,然后改用vector实现。
/*数组实现*/#include<iostream>#include<string>using namespace std;int main(){    const size_t array_size = 7;    int ia1[] = {0,1,2,3,4,5,6};    int ia2[array_size];    for(size_t ix = 0; ix !=  array_size; ++ix)    {        ia2[ix] = ia1[ix];        cout<< ia2[ix];    }    cout << endl;    return 0;}/*vector实现*/#include <vector>#include<iostream>using namespace std;int main(){    vector<int> ivec1(10, 1);//每个元素初始化为 0    vector<int> ivec2;    for (vector<int>::iterator iter = ivec1.begin();        iter != ivec1.end(); ++iter)    {   ivec2.push_back(*iter);    cout << *iter << ' ';    }    return 0;}
  1. 编写程序判断两个数组是否相等,然后编写一段类似的程序比较两个vector。
int main()  {      const int arr_size = 7;      int arr1[arr_size] = {1,2};      int arr2[arr_size] = {1,2,0};      for (int i = 0;i != arr_size; ++i)      {          if (arr1[i] != arr2[i])          {              cout << "arr1 is not equal to arr2" << endl;              break;          }      }      return 0;  }  /*比较两个vector*/#include <iostream>#include <vector>using namespace std;int main()  {      vector<int> ivec1;      vector<int> ivec2;      int ival;    //读入两个 vector  的元素值    cout << "Enter numbers for vector1(-1 to end):" <<         endl;    cin >> ival;    while (ival != -1) {        ivec1.push_back(ival);        cin >> ival;    }    cout << "Enter numbers for vector2(-1 to end):" <<         endl;    cin >> ival;    while (ival != -1) {        ivec2.push_back(ival);        cin >> ival;    }    if (ivec1 == ivec2)      {          cout << "ivec1 is equal to ivec2" << endl;      }      else      {          cout << "ivec1 is not equal to ivec2" << endl;      }      return 0;  }  

指针的引入

定义:
指针用于指向对象。与迭代器一样,指针提供对其所指对象的间接访问,只是指针结构更通用一些。与迭代器不同的是,指针用于指向单个对象,而迭代器只能用于访问容器内的元素。
1. 对指针进行初始化或赋值只能使用以下几种类型的值:
- 0值常量表达式,例如,在编译时刻获取0值的整形const对象或字面值常量0。
- 类型匹配的对象的地址。
- 另一对象之后的下一地址。

  1. 指针和引用的比较

 使用引用(reference)和指针(pointer)都可间接访问另一个值,但它们之间存在两个重要区别: (1)引用总是指向某个确定对象(事实上,引用就是该对象的别名),定义引用时没有进行初始化会出现编译错误; (2) 赋值行为上存在差异:给引用赋值修改的是该引用所关联的对象的值,而不是使该引用与另一个对象关联。引用一经初始化,就始终指向同一个特定对象。给指针赋值修改的是指针对象本身,也就是使该指针指向另一对象,指针在不同时刻可指向不同的对象(只要保证类型匹配)。

  1. 指向指针的指针
int ival = 1024;  int *pi = &ival;  int **ppi = &pi;  cout << "ival is: " << ival       << "\n*pi is: " << *pi       << "\n**ppi is: " << **ppi << endl;  

 对指向指针的指针获取其真正的值,需要进行两次解引用!

image
ppi通过两次解引用获得ival值。

  1. 输出指针元素

 初始化指针pbegin指向数组的第一个元素,而指针pend则指向该数组的超出末端的位置。
image

const size_t arr_sz = 5;  int int_arr[arr_sz] = {0,1,2,3,4};  for (int *pbegin = int_arr,*pend = int_arr+arr_sz; pbegin != pend; ++pbegin)  {      cout << *pbegin << endl;  }  
  1. 指针和const限定符
    • 指向const对象的指针

 const限定了cptr指针所指向的对象的类型,而并非cptr本身!允许用指针来改变其所指的const值。

const double *cptr; //cptr是一个指向double类型const对象的指针
  • const指针

  const指针—指针本身值不能修改,因此const指针必须在定义时初始化,而且初始化之后再也不能修改。而指针所指对象的值能否修改,则完全取决于该对象的类型。

int ivec = 0;int *const ia = &ivec;//ia是指向int型对象的const指针
  • 指向const对象的const指针

 既不能修改指针的值,也不能修改指针所指向的对象。

const double pi = 3.14159//pi_ptr is const and point to a const objectconst double *const pi_ptr = &pi;

习题

编写程序比较两个string类型的字符串,然后编写另一个程序比较两个C 风格字符串的值。

//比较两个 string  类型的字符串#include <iostream>#include <string>using namespace std;int main(){string str1, str2;//输入两个字符串cout << "Enter two strings:" << endl;cin >> str1 >> str2;//比较两个字符串if (str1 > str2)cout << "\"" << str1 << "\"" << " is bigger than "<< "\"" << str2 << "\"" << endl;else if (str1 < str2)cout << "\"" << str2 << "\"" << " is bigger than "<< "\"" << str1 << "\"" << endl;elsecout << "They are equal" << endl;return 0;}//比较两个 C  风格字符串的值#include <iostream>#include <cstring>using namespace std;int main(){//char *str1 = "string1", *str2 = "string2";const int str_size = 80;char *str1, *str2;//为两个字符串分配内存str1 = new char[str_size];str2 = new char[str_size];if (str1 == NULL || str2 == NULL) {cout << "No enough memory!" << endl;return -1;}//输入两个字符串cout << "Enter two strings:" << endl;cin >> str1 >> str2;//比较两个字符串int result;result = strcmp(str1, str2);if (result > 0)cout << "\"" << str1 << "\"" << " is bigger than "<< "\"" << str2 << "\"" << endl;else if (result < 0)cout << "\"" << str2 << "\"" << " is bigger than "<< "\"" << str1 << "\"" << endl;elsecout << "They are equal" << endl;//释放字符串所占用的内存delete [] str1 ;delete [] str2 ;return 0;}

创建动态数组

 数组类型变量有三个限制:
1)数组长度固定不变。
2)在编译时必须知道其长度。
3)数组只能在定义他的语句块内存在。
与数组变量不同,动态分配的数组将一直存在,直到程序显示的释放它为止。
1. 每个程序在执行时都占用一块可用的内存空间,用于存放动态分配的对象,此内存空间称为程序的自由存储区,或堆(heap),在C++中使用newdelete在自由存储区中分配存储空间。

int *pia = new int[10];/*new表达式分配了一个含有10个int型元素的数组,并返回指向该数组第一个元素的指针,此返回值初始化了指pia。*/int *pia2 = new int[10]()/*一对圆括号对数 组元素做初始化*/
  1. 动态空间的释放

 动态分配的内存到最后必须进行释放,否则,内存最终将会耗尽。如果不再需要使用动态创建的数组,则必须显式的将所占用的存储空间返还给程序的自由存储空间。

delete []pia;   /*不要忘记了[],即使忘记了,编译器也不会发现,但是程序运行时出错。*/
  1. 动态数组的使用

 通常就是在编译时无法知道数组的维数,所以才使用动态数组!

const char *errno = "success";     const char *errinfo = "Error: a function declaration must "                           "specify a function return type!";     const char *errTxt;     if (errFound)      errTxt = errinfo;  else      errTxt = errno;  /* *在获得字符串的长度上,必须+1,以便在动态分配内存时 *预留出存储结束符的空间 */  int dimension = strlen(errTxt) + 1;  char *errMsg = new char[dimension];  strncpy(errMsg,errTxt,dimension);  

习题

  1. 编写程序由从标准输入设备读入的元素数据建立一个 int型
    vector对象,然后动态创建一个与该 vector 对象大小一致
    的数组,把 vector 对象的所有元素复制给新数组。
#include <iostream>#include <vector>using namespace std;int main(){    vector<int> ivec;    int ival;    //读入元素数据并建立 vector    cout << "Enter numbers:(Ctrl+Z to end)" << endl;    while (cin >> ival)        ivec.push_back(ival);    //动态创建数组    int *pia = new int[ivec.size()];    //复制元素     int *tp = pia;    for (vector<int>::iterator iter = ivec.begin();        iter != ivec.end(); ++iter, ++tp)        *tp = *iter;    //释放动态数组的内存    delete [] pia;    return 0;}
  1. 编写程序从标准输入设备读入字符串,并把该串存放在字符数组中。描述你的程序如何处理可变长的输入。提供比你分配的数组长度长的字符串数据测试你的程序。
//  从标准输入设备读入字符串,并把该串存放在字符数组中#include <iostream>#include <string>#include <cstring>using namespace std;int main(){    string in_str;//  用于读入字符串的 string  对象    const size_t str_size = 10;    char result_str[str_size+1];    //  读入字符串    cout << "Enter a string(<=" << str_size        << " characters):" << endl;    cin >> in_str;    //  计算需复制的字符的数目    size_t len = strlen(in_str.c_str());    if (len > str_size)    {        len = str_size;        cout << "String is longer than " << str_size            << " characters and is stored only "            << str_size << " characters!" << endl;    }    //  复制 len  个字符至字符数组 result_str    strncpy(result_str, in_str.c_str(), len);    //  在末尾加上一个空字符(null  字符)    result_str[len+1] = '\0';    return 0;} 

为了接受可变长的输入,程序中用一个 string对象存放读入的字符串,然后使用 strncpy 函数将该对象的适当内容复制到字符数组中。因为字符数组的长度是固定的因此首先计算字符串的长度。若该长度小或等于字符数组可容纳字符串的长度,则复制整个字符串至字符数组,否则,根据数组的长度,复制字符串中前面部分的字符,以防止溢出。注意,上述给出的是满足题目要求的一个解答,事实上,如果希望接受可变长的输入并完地存放到字符数组中,可以采用动态创建数组来实现。

原创粉丝点击