《C++ Primer Plus(第六版)》(9)(第七章 函数 笔记和答案)
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);
void fun3(int a[], int size, int b) { for (int i = 0; i < size; i++) { a[i] = b; } }
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; }
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];
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; }
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; }