当前位置: 首页 > news >正文

《C++ Primer Plus(第六版)》(9)(第七章 函数 笔记和答案)

1.ANSI C是C语言的标准,任何C语言的编译器都在ANSI C的基础上扩充。

ANSI C几乎不能完成任何程序的开发。TC、VC等都对ANSI C进行了扩充,加入了自己的规则和库之类的。

对于函数头:

void fun();
在ANSI C中,意味着不指出参数,后面定义参数列表。

而C++则是表示没有函数,要是想不指出参数表,应该用省略号

void fun(...);


2.C++标准使用参数(argument)来表示实参,使用参量(parameter)来表示形参


3.带const的二级指针和非const的一级指针混合使用的时候将不安全,先看个代码

	const int **pp2;
	int * p1;
	const int n = 13;
	pp2 = &p1;//这里会报错,如果这里成功的话,
	*pp2 = &n;
	*p1 = 10;//这里就修改了常量
会报错:

 
 

error C2440: “=”: 无法从“int **”转换为“const int **”

所以:当且仅当只有一层间接关系的时候(如指针指向基本数据类型)时,才可以将非const的地址或者指针赋值给const指针。

4.指向常量的指针,是可以改变指针指向的地址。

	int a = 1;
	int b = 2;
	const int * p = &a;
	p = &b;//这个是合法的,当然不能通过p修改a和b的值。
	int* const p2 = &a;
	p2 = &b;//这个不合法,不能修改指针的内容

5.C++不允许main()调用自己。C好像可以


6.函数也有指针,函数的名字就是它的指针

int fun()
{
	return 0;
}

void CChapter2Answer::answer()
{
	cout << fun << endl;
}


这样输出的就是函数的指针。怪不得函数名不能跟变量名相同。

要指向函数的指针,要编写对应的函数原型的指针。
因为C++是强类型语言,所以把函数地址作为参数传递到别的函数中,是非常麻烦的。怪不得这么少见,而Lua这种弱类型语言则到处都是这种处理。

看了书上的介绍,函数指针真的挺繁琐,但是因为这本书是基础的,所以没有提到在哪里比较有用。


7.12复习题


1.定义函数,提供原型,调用函数,(居然不是声明、实现、调用)


2.

	void igor();
	float tofu(int i);
	double mpg(double a , double b);
	long summation(long a[], int num);
	double doctor(const char* a);
	void ofcourse(boss b);
	char* plot(map* m);


3.
void fun3(int a[], int size, int b)
{
	for (int i = 0; i < size; i++)
	{
		a[i] = b;
	}
}


4.

void fun4(int a[], int b[], int c)
{
	for (int* i = a; i != b; i++)
	{
		*i = c;
	}
}
void CChapter2Answer::answer()
{
	int a[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
	fun4(a, a + 8, 1);
}

5.
double fun5(const double a[], int b )
{
	double md = 0;
	for (int i = 0; i < b; i++)
	{
		if (i == 0)
		{
			md = a[i];
		}
		else if (md < a[i])
		{
			md = a[i];
		}
	}
	return md;
}
void CChapter2Answer::answer()
{
	double a[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
	cout << fun5(a, 8 ) << endl;
}


6.将const限定符用于指针,以防止指向的原始数据被修改。程序传递的基本类型时,将按值传递,函数使用副本。修改对原始数据没有影响。


7.char* a,char a[],带""的字符串常量


8.

double replace(char * str, char c1, char c2 )
{
	int count = 0;
	while (*str != 0)
	{
		if (*str == c1)
		{
			*str = c2;
			++count;
		}
		++str;
	}
	return count;
}
void CChapter2Answer::answer()
{
	char str[80] = "fsajasdaaffafsaaereacsd";//这里用char*,在函数里面赋值的时候就报错了。
	replace(str, 'a', 'l');
}
写这个让我明白,char*和char[]还是有所不同的。用char*等于一个字符串常量的时候,这里面的东西是不能修改的。

用char[]的时候,自己保存了一份内存,可以修改。


9.字符串可以看做它本身的地址,也是第一个字符的地址。所以*"pizza"的值是p,"taco"[2]则是c

	cout << *"pizza" << endl;
	cout << "taco"[2] << endl;
结果:

p

c


10.值传递会构建一个副本,单其实这个副本是浅复制的,如果结构里面的属性是指针,也只是复制了地址。如果不允许修改,可能会被改了内容。

指针传递的话修改了肯定会改到的。所以对于函数,很少值传递一个结构的。复制也要花时间和空间啊。

struct STest 
{
	 int a;
	 int b;
};
int funA( STest a )//值传递
{
	return a.a + a.b;
}
int funB(STest* b)//地址传递
{
	return b->a + b->a;
}
 
void CChapter2Answer::answer()
{
	STest c;
	funA(c);
	funB(&c);
}

11.

int fun(const char* a)
{
	return 1;
}

int (*funptr)(const char* a);
int judge(int (*funpter)(const char* a));

12.

struct applicant
{
	char name[30];
	int credit_ratings[3];
};

void printInfo(applicant a)
{
	cout << a.name << endl;
	for (int i = 0; i < 3; ++i)
	{
		cout << a.credit_ratings[i] << endl;
	}
}

void printInfoEx(applicant* a)
{
	cout << a->name << endl;
	for (int i = 0; i < 3; ++i)
	{
		cout << a->credit_ratings[i] << endl;
	}
}

void CChapter2Answer::answer()
{
	applicant a = { "Fable Game", { 1001, 2002, 3003 } };
	printInfo(a);
	printInfoEx(&a);
}

13.其实就是复制一下函数头,然后改一下函数名,并加个括号和星号。

struct applicant
{
	char name[30];
	int credit_ratings[3];
};

void f1(applicant * a);
const char * f2(const applicant * a1, const applicant * a2);

typedef void (*P1)(applicant * a);
typedef const char * (*P2)(const applicant * a1, const applicant * a2);
P1 p1;
P2 p2;
P1 ap[5];
P2 pa[10];


7.13 编程练习

1.

double ave(double a, double b)
{
	return 2 * a * b / (a + b);
}
void CChapter2Answer::answer()
{ 
	
	double a = 0;
	double b = 0;
	cout << "Please enter digit a:";
	cin >> a;
	cout << "Please enter digit b:";
	cin >> b;
	while ( a != 0 && b != 0 )
	{
		double c = ave(a, b);
		cout << "the ave of a, b: " << c << endl;
		cout << "Please enter digit a:";
		cin >> a;
		cout << "Please enter digit b:";
		cin >> b;
	}
}


2.真心没明白为什么要用到3个数组。。。

void printArr(int a[], int b)
{
	for (int i = 0; i < b; ++i)
	{
		cout << a[i] <<" ";
	}
	cout << endl;
}

double ave(int a[], int b)
{
	double c = 0;
	for (int i = 0; i < b; ++i)
	{
		c += a[i];
	}
	return c/b;
}
void CChapter2Answer::answer()
{ 
	const int ARRSIZE = 10;
	int a[ARRSIZE] = { 0 };
	//输入
	int actNum = 0;
	for (int i = 0; i < ARRSIZE; ++i)
	{
		cout << "Please enter the score:" ;
		int c = 0;
		cin >> c;
		if (c < 0 || !cin)
		{
			break;
		}
		a[i] = c;
		++actNum;
	}
	if (actNum <= 0)
	{
		cout << "No data" << endl;
		return;
	}
	//显示
	int b[ARRSIZE];
	memcpy(b, a, sizeof(a));//
	printArr(b, actNum);
	int c[ARRSIZE];
	memcpy(c, a, sizeof(a));//
	double d = ave(c, actNum);
	cout << "ave: " << d << endl;
}

3.

struct box 
{
	char maker[40];
	float height;
	float width;
	float length;
	float volume;
};

void printInfo(box b)
{
	cout << "maker:" << b.maker << endl;
	cout << "height:" << b.height << " width:" << b.width << " length:" << b.length << " volume:" << b.volume;
}
void computeVolume(box* b)
{
	b->volume = b->height * b->length * b->width;
}

void CChapter2Answer::answer()
{ 
	box b = { "Fable Game", 1, 32, 445, 0 };
	computeVolume(&b);
	printInfo(b);
}

4.

long double probalility(unsigned numbers, unsigned picks, unsigned otherTotal)
{
	long double result = 1.0;
	long double n;
	unsigned p;
	for (n = numbers, p = picks; p > 0; n--, p--)
	{
		result = result * n / p;
	}
	return result * otherTotal;
}
void CChapter2Answer::answer()
{ 
	unsigned total, choices, otherTotal;
	cout << "Enter the total number of choice on the game card and\n"
		"the number of picks allowed and the other total number of choice:\n";
	while ((cin >> total >> choices >> otherTotal) && choices <= total)
	{
		cout << "You have one chance in ";
		cout << probalility(total, choices, otherTotal);
		cout << " of winning.\n";
		cout << "Next three numbers (q ot quit):";
	}
	cout << "bye\n";

}

5.

long long recursion(unsigned number )
{
	if (number <= 1)
	{
		return 1;
	}
	else
	{
		return number * recursion(number - 1);
	}
	 
}
void CChapter2Answer::answer()
{ 
	unsigned num; 
	while ( cin >> num )
	{
		cout << num << "! = " << recursion(num) << endl; 
		cout << "Next num (q ot quit):";
	}
	cout << "bye\n";

}

6.


int fillArray( double a[], int num)
{
	cout << "Please enter a double:";
	double b;
	cin.clear();
	cin >> b;
	int count = 0;
	while (cin && count < num)
	{
		a[count] = b;
		count++;
		cout << "Please enter a double:";
		cin >> b;
	}
	return count;
}

void showArray(double a[], int num)
{
	cout << "show array:" << endl;
	for (int i = 0; i < num; i++)
	{
		cout << i << " : " << a[i] << endl;
	}
}

void reverseArray(double a[], int num)
{
	cout << "reverse array" << endl;
	double temp;
	for (int i = 0; i < num - 1 - i; i++)
	{
		temp = a[i];
		a[i] = a[num - 1 - i];
		a[num -1 - i] = temp;
	}
}

void CChapter2Answer::answer()
{ 
	const int Size = 20;
	double a[Size] = {0};
	int actNum = fillArray(a, Size);//填充数组
	showArray(a, actNum);//显示数组
	reverseArray(a, actNum);//反转数组
	showArray(a, actNum);//显示数组
	reverseArray(a + 1, actNum - 2);//反转数组
	showArray(a, actNum);//显示数组
}

7.

改之前的代码:

const int Max = 5;
int fill_array( double ar[], int limit)
{
	double temp;
	int i;
	for (i = 0; i < limit; i++)
	{
		cout << "Enter value #" << (i + 1) << ": ";
		cin >> temp;
		if (!cin)
		{
			cin.clear();
			while (cin.get() != '\n') continue;
			cout << "Bad input; input process terminated. \n";
			break;
		}
		else if (temp < 0)
		{
			break;
		}
		ar[i] = temp;
	}
	return i;
}

void show_array(const double ar[], int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << "Property #" << i + 1 << ": $" << ar[i] << endl;
	}
}

void revalue(double r, double ar[], int n)
{
	for (int i = 0; i < n; i++)
	{
		ar[i] *= r; 
	}
}

void CChapter2Answer::answer()
{ 
	double properties[Max];

	int size = fill_array(properties, Max);
	show_array(properties, size);
	if (size > 0)
	{
		cout << "Enter revaluation factor: ";
		double factor;
		while (!(cin >> factor))
		{
			cin.clear();
			while (cin.get() != '\n')
			{
				continue;
			}
			cout << "Bad input; Please enter a number: ";
		}
		revalue(factor, properties, size);
		show_array(properties, size);
	}
	cout << "Done. \n";
	cin.get();
	cin.get();
	
}
改之后的代码:

const int Max = 5;
double* fill_array( double ar[], int limit)
{
	double temp;
	int i;
	for (i = 0; i < limit; i++)
	{
		cout << "Enter value #" << (i + 1) << ": ";
		cin >> temp;
		if (!cin)
		{
			cin.clear();
			while (cin.get() != '\n') continue;
			cout << "Bad input; input process terminated. \n";
			break;
		}
		else if (temp < 0)
		{
			break;
		}
		ar[i] = temp;
	}
	return ar + i;
}

void show_array(const double* beginPtr, const double* endPtr)
{
	for (int i = 0; beginPtr + i != endPtr; i++)
	{
		cout << "Property #" << i + 1 << ": $" << beginPtr[i] << endl;
	}
}

void revalue(double r, double* beginPtr, double* endPtr)
{
	for (int i = 0; beginPtr + i != endPtr; i++)
	{
		beginPtr[i] *= r;
	}
}

void CChapter2Answer::answer()
{ 
	double properties[Max];

	double* endPtr = fill_array(properties, Max);
	show_array(properties, endPtr);
	if (properties != endPtr)
	{
		cout << "Enter revaluation factor: ";
		double factor;
		while (!(cin >> factor))
		{
			cin.clear();
			while (cin.get() != '\n')
			{
				continue;
			}
			cout << "Bad input; Please enter a number: ";
		}
		revalue(factor, properties, endPtr);
		show_array(properties, endPtr);
	}
	cout << "Done. \n";
	cin.get();
	cin.get();
	
}

8.

修改之前的:

const int Seasons = 4;
const std::array<std::string, Seasons> Snames = { "Spring", "Summer", "Fall", "Winter" };

void fill(std::array < double, Seasons> *pa);
void show(std::array<double, Seasons> da);
void CChapter2Answer::answer()
{ 
	std::array<double, Seasons> expenses;
	fill(&expenses);
	show(expenses);
	cin.get();
	cin.get();
}

void fill(std::array< double, Seasons> *pa)
{
	for (int i = 0; i < Seasons; i++)
	{
		cout << "Enter " << Snames[i] << " expenses:";
		cin >> (*pa)[i];
	}
}

void show(std::array<double, Seasons> da)
{
	double total = 0.0;
	for (int i = 0; i < Seasons; ++i)
	{
		cout << Snames[i] << ": $" << da[i] << endl;
		total += da[i];
	}
	cout << "Total Expenses: $" << total << endl;
}


a.

const int Seasons = 4;
const char* Snames[Seasons] = { "Spring", "Summer", "Fall", "Winter" };

void fill(double pa[], int num);
void show(double da[], int num);
void CChapter2Answer::answer()
{ 
	double expenses[Seasons];
	fill(expenses, Seasons);
	show(expenses, Seasons);
	cin.get();
	cin.get();
}

void fill(double pa[], int num)
{
	for (int i = 0; i < num; i++)
	{
		cout << "Enter " << Snames[i] << " expenses:";
		cin >> pa[i];
	}
}

void show(double da[], int num)
{
	double total = 0.0;
	for (int i = 0; i < num; ++i)
	{
		cout << Snames[i] << ": $" << da[i] << endl;
		total += da[i];
	}
	cout << "Total Expenses: $" << total << endl;
}

b.
const int Seasons = 4;
const char* Snames[Seasons] = { "Spring", "Summer", "Fall", "Winter" };
struct Expenses 
{
	double e[Seasons];
};
void fill(Expenses* pa);
void show(Expenses* da);
void CChapter2Answer::answer()
{ 
	Expenses e;
	fill(&e);
	show(&e);
	cin.get();
	cin.get();
}

void fill(Expenses* pa)
{
	for (int i = 0; i < Seasons; i++)
	{
		cout << "Enter " << Snames[i] << " expenses:";
		cin >> pa->e[i];
	}
}

void show(Expenses* da )
{
	double total = 0.0;
	for (int i = 0; i < Seasons; ++i)
	{
		cout << Snames[i] << ": $" << da->e[i] << endl;
		total += da->e[i];
	}
	cout << "Total Expenses: $" << total << endl;
}

9.

#include <iostream>

using namespace std;

const int SLEN = 30;
struct Student 
{
	char fullname[SLEN];
	char hobby[SLEN];
	int ooplevel;
};

int getinfo(Student pa[], int n)
{
	int count = 0;
	for (int i = 0; i < n; ++i)
	{
		cout << "Please enter student name:";
		cin.getline(pa[i].fullname, 80);
		if (strcmp(pa[i].fullname, "") == 0)
		{
			break;
		} 
		cout << "Please enter student hobby:";
		cin.getline(pa[i].hobby, 80); 
		cout << "Please enter student ooplevel:";
		cin >> pa[i].ooplevel;
		cin.get();
		count++;
	}
	return count;
}

void display1(Student st)
{
	cout << "student[ name: " << st.fullname << " hobby: " << st.hobby << " ooplevel: " << st.ooplevel << "]\n";
}

void display2(const Student* ps)
{
	cout << "student[ name: " << ps->fullname << " hobby: " << ps->hobby << " ooplevel: " << ps->ooplevel << "]\n";
}

void display3(const Student pa[], int n)
{
	for (int i = 0; i < n; ++i)
	{
		display2(pa + i);
	}
}

int main()
{ 
	cout << "Enter class size: ";
	int class_size;
	cin >> class_size;
	while (cin.get() != '\n')
	{
		continue;
	}
	Student* ptr_stu = new Student[class_size];
	int entered = getinfo(ptr_stu, class_size);
	for (int i = 0; i < entered; i++)
	{
		display1(ptr_stu[i]);
		display2(&ptr_stu[i]);
	}
	display3(ptr_stu, entered);
	delete[] ptr_stu;
	cout << "Done\n";
	return 0;
}

10.

#include <iostream>

using namespace std;
double add(double a, double b)
{
	cout << a + b << endl;
	return a + b;
}

double sub(double a, double b)
{
	cout << a - b << endl;
	return a - b;
}

double mul(double a, double b)
{
	cout << a * b << endl;
	return a * b;
}

double div(double a, double b)
{
	cout << a / b << endl;
	return a / b;
}

double calculate(double a, double b, double(*fun)(double, double))
{
	return fun(a, b);
}

int main()
{ 
	double(*pf[4])(double, double) = { add, sub, mul, div };
	double a, b;
	cout << "Please enter a:";
	cin >> a;
	cout << "Please enter b:";
	cin >> b;
	while (cin && b != 0)
	{
		for (int i = 0; i < 4; ++i)
		{
			calculate(a, b, pf[i]);
		}
		cout << "Please enter a:";
		cin >> a;
		cout << "Please enter b:";
		cin >> b;
	}
	return 0;
}

















转载于:https://www.cnblogs.com/fablegame/p/6430258.html

相关文章:

  • 算法导论学习笔记——计数排序算法
  • 本地化资源文件关键字重复的报错解决。
  • 数字签名是什么?
  • 探索推荐引擎内部的秘密:推荐引擎初探
  • 决策树
  • 算法导论学习笔记——基数排序
  • 算法导论学习笔记——桶排序
  • [java]删除数组中的某一个元素
  • 当你输入一个网址的时候,实际会发生什么?
  • 【转】Android下面打印进程函数调用堆栈(dump backtrace)的方法
  • 算法导论学习笔记——找数组中第i小的元素
  • 获取验证码
  • 在最坏情况下,利用n + ┌lgn┐ - 2 次比较,即可找到 n 个元素中的第2小元素
  • 牛客网上的剑指offer题目
  • 算法导论学习补充——希尔排序
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【React系列】如何构建React应用程序
  • 【技术性】Search知识
  • 11111111
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • Elasticsearch 参考指南(升级前重新索引)
  • gulp 教程
  • java多线程
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • mysql外键的使用
  • node-glob通配符
  • node入门
  • 从重复到重用
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 分享一份非常强势的Android面试题
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 关于使用markdown的方法(引自CSDN教程)
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 自定义函数
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • kubernetes资源对象--ingress
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • #{} 和 ${}区别
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (备忘)Java Map 遍历
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (十三)Flask之特殊装饰器详解
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • *** 2003
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .dwp和.webpart的区别
  • .htaccess配置重写url引擎
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET delegate 委托 、 Event 事件
  • .Net8 Blazor 尝鲜
  • .NET单元测试
  • /boot 内存空间不够