C++(12)--函數基礎:按值傳遞、傳遞數組、函數指針

模塊化編程--函數

  • 1. 函數基本知識
  • 2. 函數的參數
    • 2.1 按值傳遞機制(小議按引用傳遞)
    • 2.2 使用數組做函數參數(用戶頭文件,const的防改)
    • 2.3 使用二維數組作為函數的參數
    • 2.4 使用函數指針作為函數的參數
      • 2.4.1 函數指針的基本內容
      • 2.4.2 函數指針數組的聲明
      • 2.4.3 auto
      • 2.4.4 使用typedef 定義函數指針類型

《老九學堂C++課程》《C++ primer》學習筆記。《老九學堂C++課程》詳情請到B站搜索《老九零基礎學編程C++入門》
-------------簡單的事情重復做,重復的事情用心做,用心的事情堅持做(老九君)---------------

1. 函數基本知識

函數分類:

  1. 內置函數(STL,Boost C++)
  2. 自定義函數(focus on)

C++ Standard Library(C 標準函數,輸入/輸出,數值,診斷,通用工具,國際化,語言支持,STL(迭代器,算法, 容器))

Boost C++:可移植,開源的代碼庫

函數三要素:返回值類型,函數名,參數列表

return_type functionName(parametersList){//函數體
}

自定義函數的完整寫法:函數原型+函數調用+函數定義

int sum(int, int); // 函數原型,描述函數到編譯器的接口,提前告訴編譯器一聲。不需要寫參數名,以分號結尾
int main(){// 函數調用int result = sum(5,3);
}
// 函數定義
int sum(int num1, int num2){// 函數實現的代碼return num1 + num2
}

注意:
1.函數原型和函數定義的頭部類似,函數原型以分號結尾
2.函數原型中的參數名稱可以省略,只寫參數類型
3. C++返回值類型不能是數組,但是可以是其他任何類型(可以將數組做為結構或者對象的組成部分返回)

dmeo: 計算長方體和圓柱體的體積

//1.定義兩個函數,分別用來計算兩種形狀的體積
//2.在mian 函數中用戶可以選擇計算某個形狀的體積
void calcCuboid();   // 計算長方體的體積
void calcCylinder(); // 計算圓柱體的體積int main(){int choice = -1;while(choice){cout << "1. 計算長方體體積" << endl;cout << "2. 計算圓柱體的體積" << endl;cout << "0. 退出" << endl;cin >> choice;switch(choice){case 1:calcCuboid();break;case 2:calcCylinder();break;}}cout << "感謝使用本軟件,覺得好用點個贊唄!" << endl;return 0;
}void calcCuboid(){// 輸出長寬高double len, width, height;cout << "請輸入長寬高:" ;cin >> len >> width >> height;// 計算體積double v = len * width * height;cout << "長方體的體積為:" << v << endl;
}
void calcCylinder(){double radius, height;cout << "請輸入半徑和高:";cin >>  radius >> height;// 計算體積, pow 的頭文件 cmathdouble pi = 4 * atan(1.0); // arctan(1.0) 為45度角的弧度表示,pi為其4倍數// double v = 3.14 * pow(radius, 2) * height;double v = pi * pow(radius, 2) * height;cout << "圓柱體的體積為:" << v << endl; 
}

2. 函數的參數

2.1 按值傳遞機制(小議按引用傳遞)

按值傳遞:給函數傳遞變量時,變量值不會直接傳遞給函數,而是先制作變量值的副本,原始變量被存在棧上,將這個副本傳遞給函數。

void change(int);
int main(){int num = 9;change(num);cout << "num = " << num << endl;return 0;
}
void change(int num){num++;
}
num = 9

如果傳遞的是引用,那么原變量的值將會改變(引用,傳遞的是地址,改變的是地址中的值)

void change(int&);
int main(){int num = 9;change(num);cout << "num = " << num << endl;return 0;
}
void change(int &num){// 傳遞了引用,地址num++;
}
num = 10

2.2 使用數組做函數參數(用戶頭文件,const的防改)

1.數組作為函數參數時,只傳遞數組的首地址,并不傳遞整個數組空間
2.當數組名為實參時,數組首地址指針被傳遞到函數中

使用函數升級《小公主養成記》-- 函數放在自己寫的頭文件中(.h結尾),在.cpp文件中include

頭文件princess.h編寫:

// 使用函數升級《小公主養成記》中基本屬性的輸入和排序功能
// 基本屬性: 體力, 智力, 魅力, 道德, 氣質
#include  <iostream>using namespace std;
// 函數定義
// 給一個數組
void input(int [], int);
void show(int [], int);
//自行完成刪除和修改數組元素// 函數實現
void input(int values[], int len){//int values[] 這么定義形參,傳遞數組的時候傳遞的是數組的指針//傳數組時只有指針,建議再傳一個數組長度if(len > 5){cout << "數組長度只能是5以內,越界了" << endl;return;  // 退出返回值為void的函數}string valueNames[] = {"體力", "智力", "魅力", "道德", "氣質"};for(int i=0; i < len; i++){cout << valueNames[i] << ":" ;cin >> values[i];}
}void show(int values[], int len){string valueNames[] = {"體力", "智力", "魅力", "道德", "氣質"};for(int i = 0; i < len; i++){cout << valueNames[i] << ":" << values[i] << endl;}
}

.cpp中導入自己寫的頭文件

#include <iostream>
#include "princess.h"  // 自己寫的頭文件使用雙引號就可以了
using namespace std;
int main(){int values[5];input(values, sizeof(values)/sizeof(int));show(values,5);return 0;
}

傳遞數組參數時,不希望改動數組中的元素,在定義可以使用const 關鍵字

void show(const int [], int);
int main(){int valueArray[] = {90, 56, 67, 89, 100};return 0;
}
void show(const int valueArray[], int len){for(int i = 0; i < len; i++){// cout << valueArray[i]++ << endl;  ?,編譯不給過,告訴你只讀cout << valueArray[i]<< endl; }
}

2.3 使用二維數組作為函數的參數

void show_2d(double (*)[5],int);
int main(){double valueArray[3][5] ={{45.5, 46.6, 47.7},{12.2, 13.3, 14.4},{15.5, 16.6, 17.7}};show_2d(valueArray, 3);return 0;
}
//void show_2d(double valueArray[][5], int len)   兩種頭部書寫方式都可以
void show_2d(double (*valueArray)[5], int len){for(int i = 0; i < len; i++){for(int j = 0; j < 5; j++){cout << *(*(valueArray +i) + j) << ",";}cout << endl;}
}

2.4 使用函數指針作為函數的參數

2.4.1 函數指針的基本內容

函數的地址是其機器語言代碼在內存中存放的首地址
好處:將函數當作參數來傳遞,可以在不同的時間使用不同的函數
注意點:現有函數,先聲明函數指針,再用函數指針指向需要的函數
使用場景:在很多函數調用的情況下,使用函數指針簡化函數調用。

使用函數指針來指向一個函數的地址,函數指針的聲明

//函數原型
double sum(double, double);
//函數指針聲明, 一個指向函數的指針 ?
double (*ptrSum)(double, double);
//返回值是double * 的函數, 達不到聲明函數指針的效果
double *ptrSum(double, double);

demo1:用戶冪函數的實現與對應的指針

#include "funptr.h" 
int main(){// 聲明函數指針int (*ptrmypower)(int, int);// 讓指針指向函數ptrmypower = my_power;// 用函數指針調用函數cout << ptrmypower(2, 3) << endl;cout << (*ptrmypower)(2,3) << endl;cout << my_power(2, 3) << endl;return 0;
}

funptr.h 文件內容

int power(int, int);int my_power(int num1, int num2){int result = 1;for(int i = 0; i < num2; i++){result *= num1;}return result;
}

demo2:使用函數指針實現加減乘除運算

#include "mycalc.h"
int main(){// 定義函數指針double (*ptrCalc)(double, double);double num1, num2;char op;cout << "請輸入兩個運算數字" << endl;cin >> num1 >> num2;cout << "請輸入運算符" << endl;cin >> op;// seitch 語句只用來給函數指針賦值switch(op){case '+':// 調用加法函數ptrCalc = addtion;break;case '-':// 調用減法函數ptrCalc = subtraction;break;case '*':// 調用乘法函數ptrCalc = multiplication;break;case '\\':// 調用除法函數ptrCalc = division;break;}print_result(ptrCalc, num1, num2);return 0;
}

mycalc.h 中的內容

// 自定義計算器,使用函數指針
#include <iostream>
using namespace std;
/** 加法 */
double addtion(double, double);
/** 減法 */
double subtraction(double, double);
/** 乘法 */
double multiplication(double, double);
/** 除法 */
double division(double, double);
/** 打印結果*/
void print_result(double (*)(double, double), double, double);   // 把后兩個duuble 傳遞給前面的函數指針ptrCalcvoid print_result(double (*ptrCalc)(double, double), double num1, double num2){// 調用函數,打印結果double result = ptrCalc(num1, num2);cout << "運算結果" << result << endl;
}double addtion(double num1, double num2){return num1 + num2;
}
double subtraction(double num1, double num2){return num1 - num2;
}double multiplication(double num1, double num2){return num1 * num2;
}double division(double num1, double num2){if(num2 == 0){cout << "除數不能為0" << endl;return 0;}else{return num1 / num2;}
}

2.4.2 函數指針數組的聲明

–自行實踐

double (*ptrCalc[])(double, double)

2.4.3 auto

函數指針的聲明比較麻煩,C++ 11 中可以使用auto ptrFunc = addition; 實現函數類型的自動診斷(自動診斷需要確保變量的類型和賦值的類型一致),就可以不需要函數指針聲明。

	// double (*ptrCalc)(double, double);auto ptrCalc = addtion;     // 必須初始化,遇到具體計算需求時,在賦予新的函數地址(如后續需要求減法)

2.4.4 使用typedef 定義函數指針類型

	typedef double (*ptrCalc)(double, double);  // 定一個了一個函數指針類型ptrCalc ptrCalc1;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/444816.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/444816.shtml
英文地址,請注明出處:http://en.pswp.cn/news/444816.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于關閉SELinux的方法

原貼:http://www.diybl.com/course/6_system/linux/Linuxjs/2008629/129166.html關閉SELinux的方法&#xff1a;修改/etc/selinux/config文件中的SELINUX"" 為 disabled &#xff0c;然后重啟。如果不想重啟系統&#xff0c;使用命令setenforce 0注&#xff1a;seten…

leetcode739 每日溫度

根據每日 氣溫 列表&#xff0c;請重新生成一個列表&#xff0c;對應位置的輸入是你需要再等待多久溫度才會升高超過該日的天數。如果之后都不會升高&#xff0c;請在該位置用 0 來代替。 例如&#xff0c;給定一個列表 temperatures [73, 74, 75, 71, 69, 72, 76, 73]&#…

scp免密碼遠程拷貝

有些時候&#xff0c;我們在復制/移動文件 到另一臺機器時會用到scp&#xff0c;因為它比較安全。但如果每次都要輸入密碼&#xff0c;就比較煩了&#xff0c;尤其是在script里。不過&#xff0c;ssh有另一種用密鑰對來驗證的方式。下面寫出我生成密匙對的過程&#xff0c;供大…

C++(13)--函數的進階:內聯、傳遞引用、參數默認值、重載、函數模板

模塊化編程--函數的進階1.內聯函數1.1 inline基本情況1.2 inline 的前世今生-帶參的宏替換2.傳遞引用&#xff08;重點&#xff09;2.1引用、理由、注意事項2.3 交換兩個變量的數值3.返回引用3.1不要返回局部變量的引用3.2函數可以不返回值&#xff0c;默認返回傳入的引用對象本…

終于,我讀懂了所有Java集合——set篇

HashSet &#xff08;底層是HashMap&#xff09; Set不允許元素重復。 基于HashMap實現&#xff0c;無容量限制。 是非線程安全的。 成員變量 private transient HashMap<E,Object> map; // Dummy value to associate with an Object in the backing Map private s…

加速scp傳輸速度

當需要在機器之間傳輸400GB文件的時候&#xff0c;你就會非常在意傳輸的速度了。默認情況下(約125MB帶寬&#xff0c;網絡延遲17ms&#xff0c;Intel E5-2430&#xff0c;本文后續討論默認是指該環境)&#xff0c;scp的速度約為40MB&#xff0c;傳輸400GB則需要170分鐘&#xf…

tcpcopy使用方法

1、下載tcpcopy http://code.google.com/p/tcpcopy/downloads/list 2、配置、編譯、安裝 依此使用如下命令&#xff1a; 配置&#xff1a; ./configure 編譯&#xff1a; make 安裝&#xff1a; make install 3、使用方法 下面以mosquitto為例&#xff0c;說明tcpcopy的用法&a…

C++(14)--面向對象

面向對象1.面向對象編程(難點)2.類和對象demo1:地主類的實現版本1demo2:地主類的實現版本23.訪問修飾符demo3:外部修改成員變量不安全(版本3)demo4: 使用封裝防止直接修改成員變量&#xff08;版本3&#xff09;demo5:進一步封裝&#xff1a;設置/獲取名字&#xff0c;修改積分…

終于,我讀懂了所有Java集合——map篇(多線程)

多線程環境下的問題 1.8中hashmap的確不會因為多線程put導致死循環&#xff08;1.7代碼中會這樣子&#xff09;&#xff0c;但是依然有其他的弊端&#xff0c;比如數據丟失等等。因此多線程情況下還是建議使用ConcurrentHashMap。 數據丟失&#xff1a;當多線程put的時候&…

system函數的返回值和執行腳本的返回值

1、先統一兩個說法&#xff1a;&#xff08;1&#xff09;system返回值&#xff1a;指調用system函數后的返回值&#xff0c;比如上例中status為system返回值&#xff08;2&#xff09;shell返回值&#xff1a;指system所調用的shell命令的返回值&#xff0c;比如上例中&#x…

OJ匯總

國內&#xff1a;&#xff08;一下排名不分先后&#xff09; 浙江大學&#xff08;ZJU&#xff09;&#xff1a;http://acm.zju.edu.cn/ 北京大學&#xff08;PKU&#xff09;&#xff1a;http://acm.pku.edu.cn/JudgeOnline/ 同濟大學&#xff08;TJU&#xff09;&#xff1a;…

C++(15)--面向對象編程實踐-歡樂斗地主(vector的花式輸出)

面向對象編程實踐-歡樂斗地主《老九學堂C課程》《C primer》學習筆記。《老九學堂C課程》詳情請到B站搜索《老九零基礎學編程C入門》-------------簡單的事情重復做&#xff0c;重復的事情用心做&#xff0c;用心的事情堅持做(老九君)---------------要求&#xff1a;實現錄入及…

Google Protobuf 使用介紹

直接在 www.google.com.hk 上搜索google protobuf 后下載官方版本。 官方版本支持C\Java\Python三門語言。 還有很多非官方的語言版本支持&#xff0c;如C\NET(C#/Vb.net)\Flex(AS3)等. 要通信&#xff0c;必須有協議&#xff0c;否則雙方無法理解對方的碼流。在protobuf中&…

epoll的再次認識

使用mmap加速內核與用戶空間的消息傳遞。 這 點實際上涉及到epoll的具體實現了。無論是select,poll還是epoll都需要內核把FD消息通知給用戶空間,如何避免不必要的內存拷貝就很 重要,在這點上,epoll是通過內核于用戶空間mmap同一塊內存實現的。而如果你想我一樣從2.5內核就關…

leetcode82. 刪除排序鏈表中的重復元素 II

給定一個排序鏈表&#xff0c;刪除所有含有重復數字的節點&#xff0c;只保留原始鏈表中 沒有重復出現 的數字。 示例 1: 輸入: 1->2->3->3->4->4->5 輸出: 1->2->5 示例 2: 輸入: 1->1->1->2->3 輸出: 2->3 思路&#xff1a;判斷n…

C++(16)--運算符重載(自定義Integer類)

運算符重載1.運算符重載--重點2.友元函數--難點(流運算符重載)《老九學堂C課程》《C primer》學習筆記。《老九學堂C課程》詳情請到B站搜索《老九零基礎學編程C入門》 -------------簡單的事情重復做&#xff0c;重復的事情用心做&#xff0c;用心的事情堅持做(老九君)--------…

反應器組件 ACE_Reactor

6.1 反應器組件 ACE_Reactor反應器的基本原理是: 針對關心的某個事件寫一個事件處理器(event_handler). 將該事件處理器登記到反應器中(同時指明關心的事件). 然后反應器會自動檢測事件的發生. 并調用預先登記的事件處理器中的回調函數. 所以ACE Reactor 框架的責任&#x…

C++(17)--詳解const

詳解const《老九學堂C課程》《C primer》學習筆記。《老九學堂C課程》詳情請到B站搜索《老九零基礎學編程C入門》-------------簡單的事情重復做&#xff0c;重復的事情用心做&#xff0c;用心的事情堅持做(老九君)---------------1.const修飾成員變量 2.const修飾函數參數 3.c…

cppcheck的安裝和使用

首先從這里下載linux版本的:http://sourceforge.net/projects/cppcheck/files/cppcheck/ 然后下載對應的版本,解壓,之后安裝: 編譯: g++ -o cppcheck -Ilib cli/*.cpp lib/*.cpp 安裝: make install

leetcode24 兩兩交換鏈表中的節點

給定一個鏈表&#xff0c;兩兩交換其中相鄰的節點&#xff0c;并返回交換后的鏈表。 你不能只是單純的改變節點內部的值&#xff0c;而是需要實際的進行節點交換。 示例: 給定 1->2->3->4, 你應該返回 2->1->4->3. 思路&#xff1a;這一看就是個遞歸定義&…