c++基础复习之数组与指针
来源:互联网 发布:鬼吹灯故事解析 知乎 编辑:程序博客网 时间:2024/06/07 06:03
数组
定义: 数组是由类型名、标识符和维数组成的复合数据类型,类型名规定了存放在数组中的元素的类型,而维数则指定数组中包含的元素个数。
1. 如果没有显示提供元素初值,则数组元素会像普通变量一样初始化
- 在函数体外定义的内置数组,其元素均初始化为0;
- 在函数体内定义的内置数组,其元素无初始化;
- 不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显示初始化。
- 与vector类型相比,数组的显著缺陷在于:数组的长度是固定的,而且程序员无法知道一个给定数组的长度。数组没有获取其容量大小的size操作,也不提供push_back操作在其中自动添加元素。如果需要更改数组的长度,程序员只能创建一个更大的新数组,然后把原数组的所有元素复制到新数组空间中去。
习题(c 风格字符串)
- 编写必要的代码将一个数组赋值给另一个数组,然后改用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;}
- 编写程序判断两个数组是否相等,然后编写一段类似的程序比较两个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。
- 类型匹配的对象的地址。
- 另一对象之后的下一地址。
- 指针和引用的比较
使用引用(reference)和指针(pointer)都可间接访问另一个值,但它们之间存在两个重要区别: (1)引用总是指向某个确定对象(事实上,引用就是该对象的别名),定义引用时没有进行初始化会出现编译错误; (2) 赋值行为上存在差异:给引用赋值修改的是该引用所关联的对象的值,而不是使该引用与另一个对象关联。引用一经初始化,就始终指向同一个特定对象。给指针赋值修改的是指针对象本身,也就是使该指针指向另一对象,指针在不同时刻可指向不同的对象(只要保证类型匹配)。
- 指向指针的指针
int ival = 1024; int *pi = &ival; int **ppi = π cout << "ival is: " << ival << "\n*pi is: " << *pi << "\n**ppi is: " << **ppi << endl;
对指向指针的指针获取其真正的值,需要进行两次解引用!
ppi通过两次解引用获得ival值。
- 输出指针元素
初始化指针pbegin指向数组的第一个元素,而指针pend则指向该数组的超出末端的位置。
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; }
- 指针和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 = π
习题
编写程序比较两个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++中使用new和delete在自由存储区中分配存储空间。
int *pia = new int[10];/*new表达式分配了一个含有10个int型元素的数组,并返回指向该数组第一个元素的指针,此返回值初始化了指pia。*/int *pia2 = new int[10]()/*一对圆括号对数 组元素做初始化*/
- 动态空间的释放
动态分配的内存到最后必须进行释放,否则,内存最终将会耗尽。如果不再需要使用动态创建的数组,则必须显式的将所占用的存储空间返还给程序的自由存储空间。
delete []pia; /*不要忘记了[],即使忘记了,编译器也不会发现,但是程序运行时出错。*/
- 动态数组的使用
通常就是在编译时无法知道数组的维数,所以才使用动态数组!
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);
习题
- 编写程序由从标准输入设备读入的元素数据建立一个 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;}
- 编写程序从标准输入设备读入字符串,并把该串存放在字符数组中。描述你的程序如何处理可变长的输入。提供比你分配的数组长度长的字符串数据测试你的程序。
// 从标准输入设备读入字符串,并把该串存放在字符数组中#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 函数将该对象的适当内容复制到字符数组中。因为字符数组的长度是固定的因此首先计算字符串的长度。若该长度小或等于字符数组可容纳字符串的长度,则复制整个字符串至字符数组,否则,根据数组的长度,复制字符串中前面部分的字符,以防止溢出。注意,上述给出的是满足题目要求的一个解答,事实上,如果希望接受可变长的输入并完地存放到字符数组中,可以采用动态创建数组来实现。
- c++基础复习之数组与指针
- C语言基础之指针与数组
- C语言复习之指针数组
- C语言基础复习之指针
- C指针基础复习
- c语言基础之指针与一维数组
- C 语言复习与提高--- IV. 数组与指针
- C复习笔记(多维数组与指针)
- C 基础 (数组与指针)
- c语言基础—指针与数组
- c/c++ 基础(三) 指针与数组
- C语言基础-指针与数组
- C语言基础 指针与数组
- 指针与数组复习笔记
- 数组与指针(复习)
- C语言基础之数组、字符串、指针
- c++基础之指针与数组
- C语言之指针数组与数组指针
- Foundations of Git
- JAVA中获取文件路径的方式(根据自己理解的方式)
- 动画资源
- mysql事务,select for update,及数据的一致性处理
- 基于 exoplayer 的 videoview
- c++基础复习之数组与指针
- Xcode 诡异报错xcdatamodel: cdtool cannot compile 和 dyld: Symbol not found: ___NSDictionary0__
- poi修改word文档doc/docx不支持图片
- 新书速递:周立功教授心血新力作《面向AMetal框架与接口的编程(上)》
- SSM框架使用Maven构建环境详细整合教程(Spring+SpringMVC+MyBatis)
- 求集合的所有子集
- java 生成pdf文件
- 线上服务内存OOM问题定位三板斧
- Intellij IDEA入门到精通(一)课程发布了