#include <iostream>
using namespace std;
void func_demo();//函数的原型
/**
* 函数:要提高编程效率,可以深入学习STL和BOOST C++提供的功能
* 函数使用三步骤:
* 1. 函数的原型
* 2. 函数的定义
* 3. 函数的调用
*/
int main() {
//函数的调用
func_demo();
return 0;
}
//函数的定义
void func_demo(){
cout << "function demo" << endl;
}
复习数组和指针的关系:
#include <iostream>
#include <fstream>
using namespace std;
int main(){
int arr[4] = {1,2,3,4};
cout << arr << endl;
cout << arr+1 << endl;
cout << "---------------"<< endl;
cout << &arr[0] << endl;
cout << &arr[0]+1<< endl;
cout << "---------------"<< endl;
cout << &arr << endl;
cout << &arr+1 << endl;
cout << &arr+2 << endl;
cout << sizeof(arr) << endl;
cout << "---------------"<< endl;
cout << arr[1] << endl;
cout << *(arr+1) << endl;
cout << "---------------"<< endl;
cout << &arr[1] << endl;//0x61ff04
cout << arr+1 << endl;//0x61ff04
return 0;
}
结果如下:
0x61ff00
0x61ff04
---------------
0x61ff00
0x61ff04
---------------
0x61ff00
0x61ff10
0x61ff20
16
---------------
2
2
---------------
0x61ff04
0x61ff04
数组和指针作为参数传递:
#include <iostream>
using namespace std;
const int ArSize = 4;
int sum_arr(int arr[], int ArSize);
int sum_arr(double arr[], int ArSize);
int sum_arr02(int * arr, int ArSize);
int main(){
cout << sizeof (double *) << endl;
int arr[ArSize] = {1,2,3,4};
/**
* 这里是将arr的地址传递给了sum_arr函数
* 并不是将arr的内容 {1,2,3,4} 赋值给了 sum_arr函数的第一个参数
* 这并不违反C++值传递的方法,这里也是值传递,只是传递的是一个地址,而不是数组的内容。
*
* 而赋值给ArSize是值拷贝
* */
cout << arr << endl;
cout << sizeof arr << endl;
int sum1 = sum_arr(arr, ArSize);
cout << sum1 << endl;
int sum2 = sum_arr02(arr, ArSize);
cout << sum2 << endl;
double arr2[ArSize] = {};
sum_arr(arr2,ArSize);
return 0;
}
int sum_arr(double arr[], int ArSize){
cout << sizeof arr << endl;//4
return 0;
}
int sum_arr(int arr[], int ArSize){
//'sizeof' on array function parameter 'arr' will return size of 'int*'
cout << sizeof arr << endl;//4
cout << arr << "函数中的值" << endl;
int sum = 0;
for (int i = 0; i < ArSize; i++)
{
sum += arr[i];
}
return sum;
}
int sum_arr02(int * arr, int ArSize){
int sum = 0;
for (int i = 0; i < ArSize; i++)
{
sum += arr[i];
}
return sum;
}
进一步改进:
#include <iostream>
using namespace std;
const int ArSize = 4;
//参数定义数组的开始地址和结束地址
int sum_arr(const int *begin, const int *end);
int main()
{
int arr[ArSize] = {1, 2, 3, 4};
int sum = sum_arr(arr, arr + ArSize);
cout << sum;//10
return 0;
}
int sum_arr(const int *begin, const int *end)
{
const int *pt;
int sum = 0;
for (pt = begin; pt != end; pt++)
{
sum += *pt;
}
return sum;
}
const和指针,
//1. const修饰一个常量对象,防止使用该指针来修改所指向的值
const int age = 34;
//age = 23;//assignment of read-only variable 'age'
//int * p = &age;//invalid conversion from 'const int*' to 'int*' [-fpermissive]
const int * p = &age;//valid
//2. const修改一个指针对象,防止改变指针指向的位置
int main(){
int age1 = 34;
//*p 为const,不能被修改
//p 不是const,可以被修改
// 也就是说不能通过 *p 来修改变量age1的值
//但是可以通过age1变量来修改
const int * p = &age1;
//*p += 1;//assignment of read-only location '* p'
cout << p << endl;//0x63ff08
cout << *p << endl;//34
age1 = 23;//重新赋值
cout << *p << endl;//23
p = p+1;
cout << p;//0x63ff0c
return 0;
}
指针指向指针:
int main(){
//指针指向指针
int age = 34;
int * pd = &age;
int **pt = &pd;
cout << &age << endl;//0x63ff08
cout << pd << endl;//0x63ff08
cout << * pd << endl;//34
// ** pt = pd;
//*pt = pd;
// pd = &age
// => *pt = &age;
cout << &pd << endl;//0x63ff04
cout << pt << endl;//0x63ff04 pt指向的是pd的地址
cout << * pt << endl;//0x63ff08 *pt 保存的是pd指针的内容
cout << ** pt << endl;//34
return 0;
}
int main() {
int sloth = 3;
const int * ps = &sloth;
cout << ps << endl;//0x63ff04
//* ps = 23;//assignment of read-only location '* ps'
cout << ps+1 << endl;//0x63ff08
int * const finger = &sloth;
cout << finger << endl;//0x63ff04
* finger = 24;
cout << * finger << endl;//24
cout << finger+1 << endl;//0x63ff08
double a = 34.5;
const double * const pa = &a;
return 0;
}
//不能将const修饰的nums赋值给非const修饰的形参
const int nums[3] = { 1, 2, 3 };
函数和C-风格字符串
#include <iostream>
unsigned int c_in_str(const char * str, char ch);
char * build_str(char c, int n);
using namespace std;
int main() {
char mmm[15]="helloworld";
unsigned int count = c_in_str(mmm,'o');
cout << count << endl;
char * pstr = build_str('M', 5);
cout << &pstr[0] << endl;//MMMMM
cout << &pstr[1] << endl;//MMMM
cout << pstr[0] << endl;//M
cout << pstr[1] << endl;//M
cout << * pstr << endl;//M
cout << pstr << endl;//MMMMM
cout << (int * )pstr << endl;//0x681be8
cout << &pstr << endl;//0x63fef8
cout << (int * )(pstr+1) << endl;//0x681be9
cout << ((int *)pstr+1) << endl;//0x681bec
delete [] pstr;//释放内存,不等于变量销毁。
return 0;
}
/**
* 1. 函数和C-风格字符串
* C-风格字符串:一系列字符组成,以空值字符结尾
* 将字符串作为参数时,意味着传递的是地址,
* 可以使用const来禁止怼字符串参数进行修改
* 2. 字符串三种表示:
* 2.1 char数组(C-风格字符串和char数组重要区别:字符串有内置结束字符)
* 2.2 用引号括起来的字符串常量
* 2.3 被设置为字符串的地址的char指针
*
*/
//处理字符串中字符的标准方式
unsigned int c_in_str(const char * str, char ch){
cout << *str << endl;
unsigned int count = 0;
while(*str){ //quit 当是结束字符'\0'时,该表达式为false
if(*str == ch){
count++;
}
str++;//指针向下移动一位
}
return count;
}
//返回C-风格的字符串
//函数无妨返回一个字符串,但是可以返回一个字符串的地址
char * build_str(char c, int n){
char * pstr = new char[n+1];
cout << "build_str:"<< &pstr << endl;
pstr[n] = '\0';
while(n-- > 0){
pstr[n] = c;
}
return pstr;
}
函数和结构:
#include <iostream>
using namespace std;
struct travel_time {
int hours;
int mins;
};
const int Mins_per_hr = 60;
travel_time sum(travel_time t1, travel_time t2);
void show_time(travel_time t);
struct rect {
double x;
double y;
};
struct polar {
double r;
double angle;
};
const int Rad_to_deg = 57.3;
polar rect_to_polar(rect r);
void show_polar(polar p);
void rect_to_polar2(rect * r, polar * pda);
void show_polar2(const polar * pda);
int main() {
//1.1 传递和返回结构
travel_time t1 = { 1, 23 };
travel_time t2 = { 2, 53 };
travel_time t = sum(t1, t2);
show_time(t); //hours:4,mins:16
rect rplace = { 100, 100 };
polar p = rect_to_polar(rplace);
show_polar(p); //r:141.421 angel:44.7677degrees
//1.2 传递结构的地址
polar place;
rect_to_polar2(&rplace, &place);
show_polar2(&place); //r:141.421 angel:44.7677degrees
return 0;
}
/**
* 1. 函数和结构
*/
//1.1 传递和返回结构
travel_time sum(travel_time t1, travel_time t2) {
travel_time total;
total.mins = (t1.mins + t2.mins) % Mins_per_hr;
total.hours = (t1.hours + t2.hours) + (t1.mins + t2.mins) / Mins_per_hr;
return total;
}
void show_time(travel_time t) {
cout << "hours:" << t.hours << ",mins:" << t.mins << endl;
}
#include <cmath>
polar rect_to_polar(rect r) {
polar answer;
answer.r = sqrt(r.x * r.x + r.y * r.y);
answer.angle = atan2(r.y, r.x);
return answer;
}
void show_polar(polar p) {
cout << "r:" << p.r << endl;
cout << "angel:" << p.angle * Rad_to_deg << "degrees" << endl;
}
//1.2 传递结构的地址
void show_polar2(const polar * pda) {
cout << "r:" << pda->r << endl;
cout << "angel:" << pda->angle * Rad_to_deg << "degrees" << endl;
}
void rect_to_polar2(rect * r, polar * p) {
p->r = sqrt(r->x * r->x + r->y * r->y);
p->angle = atan2(r->y, r->x);
}
函数和string
#include <iostream>
using namespace std;
void test();
void display(const string sa[], int n);
int main() {
test();
return 0;
}
void test() {
const int SIZE = 5;
string list[SIZE]; //数组,存储了5个字符串对象
for (int i = 0; i < SIZE; i++) {
cout << i + 1 << ":";
getline(cin, list[i]);
}
cout << "your list:" << endl;
display(list, SIZE);
}
//函数和string
void display(const string sa[], int n) {
for (int i = 0; i < n; i++) {
cout << i+1 << ":" << sa[i] << endl;
}
}
函数和array
#include <iostream>
#include <array>
#include <string>
const int Seasons = 4;
const std::array<std::string, Seasons> Snames = { "Spring", "Summer", "fall",
"winter" };
//修改array
void fill(std::array<double, Seasons> * pa);
//显示array
void show(std::array<double, Seasons> da);
int main() {
std::array<double, Seasons> expenses;
fill(&expenses);
show(expenses);
return 0;
}
//修改array
void fill(std::array<double, Seasons> * pa) {
using namespace std;
for (int i = 0; i < Seasons; ++i) {
cout << "enter " << Snames[i] << " expenses:";
cin >> (*pa)[i];
}
}
//显示array
void show(std::array<double, Seasons> da) {
using namespace std;
double total = 0.0;
cout << "\n expenses: " << endl;
for (int i = 0; i < Seasons; ++i) {
cout << Snames[i] << ": $" << da[i] << " expenses:";
total += da[i];
}
cout << "total:" << total << endl;
}
//结果如下:
enter Spring expenses:23.4
enter Summer expenses:45.6
enter fall expenses:67.8
enter winter expenses:78.9
expenses:
Spring: $23.4 expenses:Summer: $45.6 expenses:fall: $67.8 expenses:winter: $78.9 expenses:total:215.7
函数指针:
#include <iostream>
#include <array>
#include <string>
double a(int lns);
double b(int lns);
void estimate(int lines, double (*pf)(int));
int main() {
using namespace std;
int lines = 5;
estimate(lines, a);//传递函数的地址
estimate(lines, b);
return 0;
}
/**
* 1. 函数指针
* 1.1 获取函数的地址: 函数名就是函数的地址
* process(think);// 将函数think的地址传递给process()
* process(think());// 将函数think()的返回值传递给process()
*
* 1.2 声明一个函数指针
* 声明某种类型的指针时,必须指定指针指向的类型。
* 同样:声明指向函数的指针时,必须指定指针指向的函数类型。
*
* 例如:
* double pam(int);//函数原型
* double (* pf)(int);// pf 指向了一个函数:接收一个int类型参数,并返回一个double类型
* 这里:pam是函数,(* pf)也是函数,那么 pf 就是函数指针
*
* 通常:
* 声明函数指针,先声明函数原型,然后将(* pf) 替换函数名。这样pf就是这类函数指针
*
* 赋值:
* double ned(int);
* double (* pf)(int);
* pf = ned;//赋值
*
* 1.3 使用函数指针来调用函数
* 调用:
* 形式1:double x = (* pf)(5);--很清晰的看出来在使用函数指针
* 形式2:double x = pf(5);
*/
double a(int lns) {
return 0.5 * lns;
}
double b(int lns) {
return 0.5 * lns + 0.02 * lns * lns;
}
void estimate(int lines, double (*pf)(int)) {
using namespace std;
cout << lines << " lines will take " << (*pf)(lines) << " hours" << endl;
}
深入理解函数指针:
#include <iostream>
#include <array>
#include <string>
//f1,f2,f3 实质是一样的
const double * f1(const double arr[], int n);
const double * f2(const double[], int n);
const double * f3(const double *, int n);
//声明一个函数指针,并初始化,指向f1
const double * (*pf)(const double arr[], int n) = f1;
//C++11 可以使用自动类型推断,声明一个函数指针,并初始化,指向f2
auto p2 = f2;
//声明一个包含三个函数指针的数组,注意[3]的位置
//这里不能使用auto.因为自动类型推断只能用于单值初始化,而不能初始化列表
const double * (*pa[3])(const double *, int n) = {f1,f2,f3};
//声明pa之后,可以使用auto再声明一个
auto pb = pa;
//数组名是指向第一个元素的指针,因此pa和pb都是指向函数指针的指针。
//如何使用它们来调用函数呢?
//const double * px = pa[0](av,3); 调用第一个函数
//const double * px = (*pa[1])(av,3); 调用第二个函数
//获取函数返回的double的值
//double x = *pa[0](av,3);
//double y = *(*pb[1])(av,3);
//创建指向整个数组的指针。
//1. 用自动类型推断
auto pc = &pa;
//2. 使用声明的类型
const double * (*(*pd)[3])(const double *, int) = &pa;
int main() {
using namespace std;
return 0;
}
网友评论