c++笔记2(参考learncpp.com)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c++笔记2(参考learncpp.com),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6087字,纯文字阅读大概需要9分钟。
内容图文
![c++笔记2(参考learncpp.com)](/upload/InfoBanner/zyjiaocheng/626/31065b219a6945859e6f934a4bcb7d79.jpg)
由于learncpp.com内容过多,此篇博客记录后半部分,前半部分请移步我的博客c++笔记1(参考learncpp.com)
1、函数传参的3种方式,引用实现多返回值函数
3种传参方式:值传递、引用传递、地址传递。
单个基本数据类型,用值传递。
其他类型(string、array等)用引用传递,若不想参数被更改,用const修饰。
引用、指针需要注意的是函数参数必须为左值(如i=5,i是左值,5是右值),因为这两者有“地址”观念。
int foo1(int x); // pass by value int foo2(int &x); // pass by reference int foo3(int *x); // pass by address int i {}; foo1(i); // i不被更改,因为有拷贝 foo2(i); // i可能被改,若不想被改,用int foo2(const int &x); foo3(&i); // i可能被改
引用实现多返回值函数
#include <iostream> #include <cmath> // for std::sin() and std::cos() void getSinCos(double degrees, double &sinOut, double &cosOut) { static constexpr double pi { 3.14159265358979323846 }; // the value of pi double radians = degrees * pi / 180.0; //度转为弧度,如30°→Π/6 sinOut = std::sin(radians); cosOut = std::cos(radians); } int main() { double sin(0.0); double cos(0.0); getSinCos(30.0, sin, cos); std::cout << "The sin is " << sin << '\n'; std::cout << "The cos is " << cos << '\n'; return 0; }
另外可以参考我的另外一篇博客,函数间参数传递的3种方式
2、函数多返回值的3种实现方式
方式一:引用,参考上节内容。OpenCV图像处理框架中常见此用法。
方式二:结构体。
#include <iostream> struct S { int m_x; double m_y; }; S returnStruct() //返回结构体 { S s; s.m_x = 5; s.m_y = 6.7; return s; } int main() { S s{ returnStruct() }; std::cout << s.m_x << ' ' << s.m_y << '\n'; return 0; }
方式三:元组 std::tuple。
#include <tuple> #include <iostream> std::tuple<int, double> returnTuple() // 返回元组 { return { 5, 6.7 }; } int main() { std::tuple s{ returnTuple() }; // 调用函数 std::cout << std::get<0>(s) << ' ' << std::get<1>(s) << '\n'; // 用std::get<n>获取元组中元素 /*或者使用如下方式 int a; double b; std::tie(a, b) = returnTuple(); // 用std::tie拆解元组 //auto [a,b]{returnTuple()}; // c++17,效果同上,拆解元组 std::cout << a << ' ' << b << '\n'; */ return 0; }
3、指向函数地址的指针,std::function的使用
功能:
① 函数指针主要用于在数组(或其他结构)中存储函数,
② 在需要将函数(此函数又称回调函数)传递给另一个函数时。
因为声明函数指针的本机语法很难看而且容易出错,所以我们建议使用std::function。
严格按以下格式定义:
int (*fcnPtr)(); //指针fcnPtr是指向“无参且返回int型”函数的指针,fcnPtr可指向任何同类型的函数。
int (*const fcnPtr)(); //const函数
如下3种等效,fcnPtr指向“两个参数int、double型且返回int型”的函数
int (*fcnPtr)(int,double);
std::function<int(int,double)> fcnPtr; //<返回类型(每个参数类型)>
auto fcnPtr;
#include <iostream> // #include <functional> //for std::function int foo(){ return 5;} int goo(){ return 6;} void main() { int(*fcnPtr)(){&foo}; //指针只能指向“无参且返回int型”的函数 //auto fcnPtr{ &foo }; //使用auto关键字,同上等效 //std::function<int()> fcnPtr{ &foo }; //使用std::function,同上等效 fcnPtr=&goo; //指向函数goo的地址,不需要() std::cout << fcnPtr(); //隐式使用,更简洁 //std::cout << (*fcnPtr)(); //显式使用,同上等效 }
注意,带默认参数的函数,必须显式地传递任何默认参数的值。默认参数是在编译时解析的,而函数指针是在运行时解析的。因此,当使用函数指针进行函数调用时,无法解析默认参数。
【函数作为参数实现升序、降序】
#include <utility> // for std::swap #include <iostream> // 作为参数的函数,又称回调函数,含两个int参数、返回bool。ascending、descending两个回调函数。 void selectionSort(int *array, int size, bool(*comparisonFcn)(int, int)) { // 前 n-1个元素,与之后的比较大小 for (int startIndex{ 0 }; startIndex < (size - 1); ++startIndex) { int bestIndex{ startIndex }; //存储最大或最小元素的下标 // 后n-1个元素 for (int currentIndex{ startIndex + 1 }; currentIndex < size; ++currentIndex) { if (comparisonFcn(array[bestIndex], array[currentIndex])) // 使用回调函数作为判断条件 { bestIndex = currentIndex; // 存储最大或最小元素的下标 } } // 交换元素,之前是交换下标 std::swap(array[startIndex], array[bestIndex]); } } // 回调函数,bool类型当作触发升序的“开关” bool ascending(int x, int y) { return x > y; // 前>后则返回true,true则触发交换 } // 回调函数 bool descending(int x, int y) { return x < y; } void printArray(int *array, int size) //数组会退化为指针,丢失长度信息,所以显式指定 { for (int index{ 0 }; index < size; ++index) { std::cout << array[index] << ' '; } std::cout << '\n'; } int main() { int array[9]{ 3, 7, 9, 5, 6, 1, 8, 2, 4 }; // 降序 selectionSort(array, 9, descending); printArray(array, 9); // 升序 selectionSort(array, 9, ascending); printArray(array, 9); return 0; }
4、?5个内存区域(又称为段)
The code segment (also called a text segment),代码段(也称为文本段),编译后的程序位于内存中,代码段通常是只读的。
The bss segment (also called the uninitialized data segment),bss段(也称为未初始化数据段),用于存储未初始化的全局变量和静态变量。
The data segment (also called the initialized data segment),数据段(也称为初始化的数据段),用于存储初始化的全局变量和静态变量。
The heap,堆段,从堆中动态分配的变量。
The call stack,调用堆栈,其中存储函数参数、局部变量和其他函数相关信息。
5、std::vector的堆栈操作(Stack behavior)
Stack 是后进先出的结构(LIFO),如果你在堆栈顶部放一个新盘子,从堆栈中移出的第一个盘子将会是你最后推入的盘子。当项目被推入堆栈时,堆栈会变得更大。当项目被弹出时,堆栈会变得更小。
【容量与长度】
int *array{ new int[10] { 1, 2, 3, 4, 5 } }; //容量是10,长度是5。
容量会依据长度自动扩容,但未必会随着长度缩小。
#include <iostream> #include <vector> int main() { std::vector<int> array{ 0, 1, 2 }; std::cout << "length: " << array.size() << " capacity: " << array.capacity() << '\n'; array.resize(5); // 长度变为5,元素变为0,1,2,0,0 std::cout << "length: " << array.size() << " capacity: " << array.capacity() << '\n'; array.resize(2); // 长度变为2,元素只剩0,1 std::cout << "length: " << array.size() << " capacity: " << array.capacity() << '\n'; }
【堆栈操作】
push_back() 将元素压入堆栈。堆栈变大。
back() 返回堆栈顶部元素的值。堆栈不变,只是看最顶部的元素。
pop_back() 从堆栈中弹出一个元素。堆栈变小。
std::vector<int> stack{}; stack.push_back(5); stack.push_back(3); stack.push_back(2); //stack中元素5,3,2 std::cout << "top: " << stack.back() << '\n'; // 2 stack.pop_back(); //拿走最顶部的2,stack中元素剩5,3
最终stack容量为3,长度为2
内容总结
以上是互联网集市为您收集整理的c++笔记2(参考learncpp.com)全部内容,希望文章能够帮你解决c++笔记2(参考learncpp.com)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。