zoukankan      html  css  js  c++  java
  • C++学习3--编程基础(vector、string、三种传参)

    知识点学习

    Vector容器

    • vector是C++标准程序库中的一个类,其定义于头文件中,与其他STL组件一样,ventor属于STD名称空间;

    • ventor是C++标准程序库里最基本的容器,设计之初是为了改善C语言原生数组的种种缺失和不便,而欲提供一种更有效,安全的数组;

    根据使用功能大概分为几个部分

    • 访问元素的方法

    ven[i] 访问索引值为i的引用
    ven.back() 返回ventor最尾元素的引用

    • 新增或移动元素的方法

    vec.push_back() 新增元素至ventor的尾端,必要时会进行存储器配置;

    vec.pop_back() 删除ventor最尾端的元素

    vec.insert() 插入或多个元素至ventor内的任意位置

    vec.erase() 删除ventor中一个或多个元素

    vec.clear() 清空所有元素

    • 获取长度/容量

    vec.size() 获取vector目前持有的元素个数
    vec.empty() 如果vector内部为空,则传回true值

    • 迭代(iterator)

    • vec.begin() 返回一个迭代器,指向vector第一个元素

    • vec.end() 返回一个迭代器,它指向vector最尾端元素的下一个位置(不是最末元素)尾地址不指向任何存储的元素,而是标志vector的结束。

    string

    string是c++标准程序库中的一个头文件,定义了C++标准中的字符串的基本模板类std::basic_string及相关的模板类实例:

    经常用到的功能:

    • 《字符访问》

    string::at

    访问特定字符,带边界检查

    string:: operator[]

    访问特定字符

    string::front

    访问第一个字符

    string::back

    访问最后一个字符

    string::data

    访问基础数组

    string:: substr

    以子串构造一个新串,参数为空时取全部源串

    string:: clear

    清空内容

    string:: erase

    删除一个或一段字符

    string:: push_back

    追加1个字符

    string:: pop_back

    删除最后1个字符,C++11标准导入

    函数传参定义

    1. 三种传参方式比较

    值传递:实参要初始化形参要分配空间,将实参内容拷贝到形参;

    指针传递:本质仍是值传递;

    引用传递:实参初始化形参的时候不分配空间;

    1. 函数的返回值

    通过函数调用使主调函数能得到一个确定的值,这就是函数的返回值

    1)函数的返回值是通过函数中的return语句获得的;

    return语句将被调用函数中的一个确定值带回主调函数中去。
    

    2)函数值的类型,既然函数有返回值,这个值当然应属于某一个确定的类型,应当在定义函数时指定函数值的类型;

    return后面的语句可以是变量、常量、表达式、函数;
    

    3)在定义函数时指定的函数类型一般应该和return语句中的表达式类型一致。

    如果函数值的类型和return语句中表达式的值不一致,则以函数类型为准。对数值型数据,可以自动进行类型转换。即函数类型决定返回值的类型;
    

    4)对于不带返回值的函数,应当“void”定义函数为“无类型”(或称“空类型”),这样系统就保证不使用函数带回任何值,即禁止调用函数中使用被调用函数的返回值。

    linux GCC编译方法

     g++ -std=c++11 test.cpp -o test
    

    建议完成《C++ primer 第五版》练习

    练习题 4.21

    使用条件运算符从ventor中找到哪些元素的值是奇数,然后将这些奇数翻倍

     #include "stdafx.h"
    #include <vector>
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::vector;
    
    int main() 
    {
    	vector<int> ivec{1,2,3,4,5,6,7,8,9,10};
    	//如果是奇数I乘以2,否则输出
    	for (auto & i : ivec)
    	{
    		i = (i % 2) ? (i * 2) : i;
    	}
    
    	for (auto i : ivec)
    	{
    		cout << i << "" << endl;
    	}
    	return 0;
    }
    
    

    5.5 写一段自己的程序,使用if else语句实现把数字成绩转换成字母成绩的要求

    int main()
    {
    	vector<string> scores = { "F","D","C","B","A","A++" };
    
    	int grade{ 0 };
    
    	while (cin >> grade)
    	{
    		string lettergrade;
    		if (grade<60)
    		{
    			lettergrade = scores[0];
    		}
    		else 
    		{
    			lettergrade = scores[(grade - 50) / 10];
    			if (grade != 100)
    			{
    				if (grade % 10 > 7)     //个位数大于7,那么加上 + 号
    				{
    					lettergrade += "+";
    				}
    				else if (grade % 10 <3) //个位数小于3,那么加上 - 号
    				{
    					lettergrade += "-";
    				}
    			}
    		}
    
    		cout << lettergrade << endl;
    	}
    
    
        return 0;
    }
    

    练习题 5.14

    编写一段程序,从标准输入中读取若干string对象并查找连续重复出现的单词。所谓连续重复出现的意思是:一个单词后面紧跟着这个单词本身。要求记录连续重复出现的最大次数以及对应的单词,如果这样的单词存在,输出重复出现的最大次数,如果不存在,输出一条信息说明任何单词都没有连续出现过。例如,如果输入时
    how now now now brown cow cow
    那么输出应该表明单词now连续出现了3次

    
    #include "stdafx.h"
    #include <string>
    #include <iostream>
    using std::cout;
    using std::cin;
    using std::endl;
    using std::string;
    string pre_word, word, max_repeat_word;
    int repeat_time = 0, max_repeat_time = 0;
    
    int main()
    {
    	while (cin>>word)
    	{
    		if (word == pre_word)
    		{
    			++repeat_time;
    		}
    		else 
    		{
    			repeat_time = 1;
    			pre_word = word;
    		}
    
    		if (max_repeat_time < repeat_time)
    		{
    			max_repeat_time = repeat_time;
    			max_repeat_word = pre_word;
    
    		}
    
    		if (max_repeat_time > 4)
    		{
    			break;
    		}
    
    	}
    
    	if (max_repeat_time<=1)
    	{
    		cout << "no word was repeated" << endl;
    	}
    	else
    	{
    		cout << "the word '" << max_repeat_word << "' occurred " << max_repeat_time << " times " << endl;
    	}
    
    
        return 0;
    }
    
    
    

    练习题 5.17

    假设有两个包含整数的vector对象,编写一段程序,检验其中一个vector对象是否是另一个的前缀。为了实现这一目标,对于两个不等长的vector对象,只需挑出长度较短的那个,把它的所有元素和另一个vector对象比较即可。例如如果两个vector对象的元素分别是0、1、1、2和0、1、1、2、3、5、8,则程序的返回结果应该为真;

    #include "stdafx.h"
    #include <iostream>
    #include <vector>
    using std::cout;
    using std::endl;
    using std::vector;
    
    int main()
    {
    	vector<int> vec1{ 0,1,1,2 };
    	vector<int> vec2{ 0,1,1,2,3,5,8 };
    
    	auto size = vec1.size() < vec2.size() ? vec1.size() : vec2.size();
    	for (decltype(vec1.size()) i = 0 ; i != size; ++i)
    	{
    		if (vec1[i] != vec2[i])
    		{
    			cout << "false" << endl;
    			return 0;
    		}
    	}
    	cout << "true" << endl;
        return 0;
    }
    

    练习题 5.20

    编写一段程序,从标准输入中读取string对象的序列直到连续出现两个相同的单词或者所有单词都读完位置。使用while循环一次读取一个单词,当一个单词连续出现两次时使用break语句终止循环。输出连续重复出现的单词,或者输出一个消息说明没有任何单词是连续重复的。

    #include "stdafx.h"
    #include <string>
    #include <iostream>
    using std::cout;
    using std::cin;
    using std::endl;
    using std::string;
    
    
    int main()
    {
    	string read, tmp;
    	while (cin >> read)
    	{
    		if (read == tmp)
    		{
    			break;
    		}
    		else 
    		{
    			tmp = read;
    		}
    	}
    	//输入流的末尾内容
    	if (cin.eof())
    	{
    		cout << "no word was repeated." << endl;
    	}
    	else 
    	{
    		cout << read << " occurs twice in succession." << endl;
    	}
    
        return 0;
    }
    

    第6章函数

    练习题 6.4

    编写一个与用户交互的函数,要求用户输入一个数字,计算生成该数字的阶乘,在main函数中调用该函数,计算阶乘结果有多少个0

    int jiecheng(int chengshu)
    {
    	int Sum = 1;
    	int nCount = 0;
    	for (int i=1;i<=chengshu;i++)
    	{
    		Sum = i*Sum;
    	}
    	cout << endl;
    	cout << "阶乘数" << Sum;
    	for (;Sum;)
    	{
    		if (Sum%10==0)
    		{
    			nCount++;
    		}
    		Sum = Sum / 10;
    	}
    
    
    	return nCount;
    
    }
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int nNum;
    	cin >> nNum;
    	nNum = jiecheng(nNum);
    	cout << endl;
    	cout << nNum;
    
    	return 0;
    }
    
    练习题 6.10

    编写一个函数,使用指针形参交换两个数的值,在函数中调用并输出交换后的结果;

    void swap(int * lhs, int * rhs)
    {
    	int tmp;
    	 tmp = *lhs;
    	*lhs = *rhs;
    	*rhs = tmp;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int nNumA = 10;
    	int nNumB = 20;
    
    	swap(&nNumA, &nNumB);
    
    	cout << nNumA << " " << nNumB;
    
    	return 0;
    }
    
    
    练习题 6.12

    使用引用而非指针交换两个整数的值,那种方式比较易于使用呢?

    • 拷贝大的类类型对象或者容器对象比较低效,当某种类型不支持拷贝操作时,函数只能通过引用形参访问该类型的对象;
    • 引用一经初始化不能再引用其他变量,而指针可以(非const指针)
    #include <iostream>
    #include <string>
    
    void swap(int& lhs, int& rhs)
    {
        int temp = lhs;
        lhs = rhs;
        rhs = temp;
    }
    
    int main()
    {
        for (int left, right;
             std::cout << "Please Enter:
    ", std::cin >> left >> right;) {
            swap(left, right);
            std::cout << left << " " << right << std::endl;
        }
    
        return 0;
    }
    
    练习题 6.17

    编写一个函数,判断string对象中是否有大写字母,编写另外一个函数把string对象全都改成小写形式。这两个函数中你使用的形参类型相同吗?

    #include "stdafx.h"
    #include <windows.h>
    #include <iostream>
    #include <string>
    using std::cout;
    using std::cin;
    using std::endl;
    using std::string;
    bool hasUpercase(const string & str) 
    {
    	for (auto c :str)
    	{
    		if (isupper(c))
    		{
    			return true;
    		}
    		
    	}
    	return false;
    }
    const string & makeLowercase(string & str) 
    {
    	for (auto & c : str)
    	{
    		if (isupper(c))
    		{
    			c = tolower(c);
    		}
    	}
    	return str;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	string str("Hello World");
    	cout << "类型是否是大写" << endl;
    	cout << hasUpercase(str) << endl;
    	
    	cout << "转换小写函数";
    	cout << makeLowercase(str) << endl;
    
    	return 0;
    }
    
    练习题 6.22

    编写一个函数,令其交换两个init指针;

    #include "stdafx.h"
    #include <windows.h>
    #include <iostream>
    using std::cout;
    using std::cin;
    using std::endl;
    
    void swap(int * & lft, int * & rht) 
    {
    	auto tmp = lft;
    	lft = rht;
    	rht = tmp;
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    
    	int i = 42;
    	int j = 99;
    
    	auto lft = &i;
    	auto rht = &j;
    
    	swap(lft, rht);
    
    	cout << *lft << "  " << *rht << endl;
    	return 0;
    }
    
    
    练习题 6.36

    编写一个函数声明,使其返回数组的引用并且该数组包含10个string对象,不要尾置返回类型、decltype或者类型别名;

    string (&func(string (&arrStr)[10]))[10]
    
  • 相关阅读:
    《c++ templates》学习笔记(8)——第十一章 模板实参演绎
    关于Decorator模式
    《c++ templates》学习笔记(11)——第十章 实例化
    《c++ templates》学习笔记(5)——第六章 模板实战
    《c++ templates》学习笔记(9)——第十二章 特化与重载
    关于windows Power Shell (1)
    VC版的IniFile
    《c++ templates》学习笔记(6)——第七章 模板术语
    《c++ templates》学习笔记(4)——第五章,技巧性基础知识
    boost::test
  • 原文地址:https://www.cnblogs.com/17bdw/p/6040510.html
Copyright © 2011-2022 走看看