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]
    
  • 相关阅读:
    训练总结
    图论--最短路--SPFA模板(能过题,真没错的模板)
    图论--最短路-- Dijkstra模板(目前见到的最好用的)
    The 2019 Asia Nanchang First Round Online Programming Contest B Fire-Fighting Hero(阅读理解)
    关于RMQ问题的四种解法
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 K题 center
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 XKC's basketball team
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 D Carneginon
    ZOJ 3607 Lazier Salesgirl (枚举)
    ZOJ 3605 Find the Marble(dp)
  • 原文地址:https://www.cnblogs.com/17bdw/p/6040510.html
Copyright © 2011-2022 走看看