《C++ Primer Plus(第六版)》(9)(第七章 函数 笔记和答案)
2016-12-05 21:04
861 查看
1.ANSI C是C语言的标准,任何C语言的编译器都在ANSI C的基础上扩充。
ANSI C几乎不能完成任何程序的开发。TC、VC等都对ANSI C进行了扩充,加入了自己的规则和库之类的。
对于函数头:
而C++则是表示没有函数,要是想不指出参数表,应该用省略号
2.C++标准使用参数(argument)来表示实参,使用参量(parameter)来表示形参
3.带const的二级指针和非const的一级指针混合使用的时候将不安全,先看个代码
error C2440: “=”: 无法从“int **”转换为“const int **”
所以:当且仅当只有一层间接关系的时候(如指针指向基本数据类型)时,才可以将非const的地址或者指针赋值给const指针。
4.指向常量的指针,是可以改变指针指向的地址。
5.C++不允许main()调用自己。C好像可以
6.函数也有指针,函数的名字就是它的指针
这样输出的就是函数的指针。怪不得函数名不能跟变量名相同。
要指向函数的指针,要编写对应的函数原型的指针。
因为C++是强类型语言,所以把函数地址作为参数传递到别的函数中,是非常麻烦的。怪不得这么少见,而Lua这种弱类型语言则到处都是这种处理。
看了书上的介绍,函数指针真的挺繁琐,但是因为这本书是基础的,所以没有提到在哪里比较有用。
7.12复习题
1.定义函数,提供原型,调用函数,(居然不是声明、实现、调用)
2.
3.
4.
5.
6.将const限定符用于指针,以防止指向的原始数据被修改。程序传递的基本类型时,将按值传递,函数使用副本。修改对原始数据没有影响。
7.char* a,char a[],带""的字符串常量
8.
用char[]的时候,自己保存了一份内存,可以修改。
9.字符串可以看做它本身的地址,也是第一个字符的地址。所以*"pizza"的值是p,"taco"[2]则是c
p
c
10.值传递会构建一个副本,单其实这个副本是浅复制的,如果结构里面的属性是指针,也只是复制了地址。如果不允许修改,可能会被改了内容。
指针传递的话修改了肯定会改到的。所以对于函数,很少值传递一个结构的。复制也要花时间和空间啊。
11.
12.
13.其实就是复制一下函数头,然后改一下函数名,并加个括号和星号。
7.13 编程练习
1.
2.真心没明白为什么要用到3个数组。。。
3.
4.
5.
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;
}
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;
}
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;
}
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.
9.
#include <iostream>
using namespace std;
const int SLEN = 30;
struct Student
{
char fullname[SLEN];
char hobby[SLEN];
int ooplevel;
};
10.
#include <iostream>
using namespace std;
double add(double a, double b)
{
cout << a + b << endl;
return a + b;
}
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; }
相关文章推荐
- C++ Primer Plus 第六版 学习笔记 第七章 编程练习答案
- 《C++ Primer Plus(第六版)》(2)(第三章 处理数据 笔记和答案)
- 《C++ Primer Plus(第六版)》(16)(第十章 对象和类 笔记和复习题答案)
- 2012/1/19 《C++ Primer Plus》第七章:函数——C++编程模块 学习笔记
- C++ Primer Plus第六版 第七章 编程练习答案
- C++ primer plus(第六版)学习笔记、习题答案(2)
- 《C++ Primer Plus(第六版)》(11)(第八章 函数探幽 复习题答案)
- C++ primer plus(第六版)学习笔记、习题答案(1)
- 《C++ Primer Plus(第六版)》(12)(第八章 函数探幽 编程题答案)
- C++ primer plus(第六版)学习笔记、习题答案(4.2)
- 《C++ Primer Plus(第六版)》(1)(第二章 开始学习C++ 笔记和答案)
- C++ primer plus(第六版)学习笔记、习题答案(4)
- C++ Primer plus 学习笔记之第七章(2)函数指针
- 《C++ Primer Plus(第六版)》(10)(第八章 函数探幽 笔记)
- 《C++ Primer Plus(第六版)》(8)(第六章 分支语句和逻辑运算符 笔记和答案)
- C++ primer plus(第六版)学习笔记、习题答案(3)
- C++ primer plus(第六版)学习笔记、习题答案(5)
- 2012/1/19 《C++ Primer Plus》第七章:函数——C++编程模块 学习笔记
- C++ PRIMER PLUS (第六版) 中文版 第七章编程练习答案
- C++PRIMER PLUS第六版课后编程答案 5.1-5.5