C/C++程式設計學習筆記二:C語言的函式中,如何使用指標交換兩個數的值,深入理解指標
使用外部函式交換兩個變數的值,一個再簡單不過的事情,但是在C/C++中,正確實現該功能反應了你對指標和引用等重要知識的掌握程度。本文列舉了幾種常見的寫法,其中前三種是錯誤的,後兩種是正確的。第四種使用的是指針,第五種使用的是引用。請看下面五個簡單的函式:
<span style="font-size:18px;">#include<iostream> using namespace std; int fun1 (int a,int b) { int c; c=a;a=b;b=c; cout<<"a1:"<<a<<";b1:"<<b<<endl; } int fun2 (int *a,int *b) { int *c; c=a;a=b;b=c; cout<<"a2:"<<*a<<";b2:"<<*b<<endl; } int fun3(int *a,int *b) { int *c; c=*a;*a=*b;*b=c; cout<<"a3:"<<*a<<";b3:"<<*b<<endl; } int fun4 (int *a,int *b) { int c; c=*a;*a=*b;*b=c; cout<<"a4:"<<*a<<";b4:"<<*b<<endl; } int fun5 (int &a,int &b) { int c; c=a;a=b;b=c; cout<<"a5:"<<a<<";b5:"<<b<<endl; } int main() { int aa=1,bb=2; fun1(aa,bb); cout<<"aa1:"<<aa<<";bb1:"<<bb<<endl; fun2(&aa,&bb); cout<<"aa2:"<<aa<<";bb2:"<<bb<<endl; fun3(&aa,&bb); cout<<"aa3:"<<aa<<";bb3:"<<bb<<endl; fun4(&aa,&bb); cout<<"aa4:"<<aa<<";bb4:"<<bb<<endl; aa=1,bb=2; fun5(aa,bb); cout<<"aa5:"<<aa<<";bb5:"<<bb<<endl; return 0; } </span>
輸出結果為:
<span style="font-size:18px;">a1:2;b1:1
aa1:1;bb1:2
a2:2;b2:1
aa2:1;bb2:2
aa3:1;bb3:2
a4:2;b4:1
aa4:2;bb4:1
a5:2;b5:1
aa5:2;bb5:1</span>
fun1(),如果使用java或者其它高階語言,使用該函式沒什麼問題,甚至是天經地義的,但是C和C++裡卻不行,原因是main中呼叫fun1()時,將實參a,b的值傳遞給了交換函式,如果此時在swap1中列印,可以看到結果是正確的,但是該過程其實是將aa和bb分別複製了一份給了函式,執行完fun1()之後,aa和bb的值沒有任何變化。
fun2(),看似的確使用了指標,但任然失敗,為什麼呢?其實這裡是將aa和bb的地址給交換了,而並沒有交換aa和bb的值。在這裡由於未給c賦值,c中並沒有確定的值,c中的值是不可預見的。此時c可能指向一個未知的儲存單元。而嚴重的情況是,該單元的資料可能是有用的,因此fun2()不但沒有實現兩個數的交換,反而給系統的穩定性帶來威脅。
fun3(),將int賦值給int *,編譯錯誤。
fun4()是正確的。為了在函式中改變了的變數能被其它函式呼叫,正確的辦法是用指標變數作為函式引數,在函式執行過程中使指標變數所指向的變數值發生變化,函式呼叫結束後,哲別變量值的變化依然保留下來,這樣就實現了通過函式呼叫是變數的值發生變化,在其它函式中可以使用這些改變了的值的目的。
fun5()也是正確的,這是引用的重要應用之一。對於引用的操作實際上是作用在引用所因的物件上。
相關推薦
C/C++程式設計學習筆記二:C語言的函式中,如何使用指標交換兩個數的值,深入理解指標
使用外部函式交換兩個變數的值,一個再簡單不過的事情,但是在C/C++中,正確實現該功能反應了你對指標和引用等重要知識的掌握程度。本文列舉了幾種常見的寫法,其中前三種是錯誤的,後兩種是正確的。第四種使
FFmpeg程式設計學習筆記二:音訊重取樣
ffmpeg實現音訊重取樣的核心函式swr_convert功能非常強大,可是ffmpeg文件對它的註釋太過簡單,在應用中往往會出這樣那樣的問題,其實在讀取資料->重取樣->編碼資料的迴圈中在第一次執行swr_convert後還應用swr_conve
《C語言程式設計:現代方法(第2版)(K.N.King 著)》學習筆記一:C語言概述
1.1 C語言的歷史 1.1.1 起源 C語言是美國貝爾實驗室的 Dennis Ritchie、Ken Thompson 等人為開發 UNIX 作業系統而於 1972 年設計的一種計算機程式語言。
《C語言程式設計:現代方法(第2版)(K.N.King 著)》學習筆記三:C語言基本概念(2)
2.3 註釋 每一個程式都應該包含識別資訊,即程式名、編寫日期、作者、程式的用途以及其他相關資訊。C語言把這類資訊放在註釋(comment)中。 符號 /* 標記註釋的開始,而符號 */ 則標記註釋
《C語言程式設計:現代方法(第2版)(K.N.King 著)》學習筆記四:C語言基本概念(3)
2.5 讀入輸入 為了獲取輸入,就要用到 scanf 函式。它是C函式庫中與 printf 相對應的函式。scanf 中的字母 f 和 printf 中的字母 f 含義相同,都是表示“格式化”的意思
《C語言程式設計:現代方法(第2版)(K.N.King 著)》學習筆記五:C語言基本概念(4)
2.7 識別符號 在編寫程式時,需要對變數、函式、巨集和其他實體進行命名。這些名字稱為識別符號(identifier)。在C語言中,識別符號可以含有字母、數字和下劃線,但是必須以字母或者下劃線開頭。
《C語言程式設計:現代方法(第2版)(K.N.King 著)》學習筆記六:C語言基本概念(5)
問與答 GCC 最初是 GNU C Compiler 的簡稱。現在指 GNU Compiler Collection,這是因為最新版本的 GCC 能夠編譯用 Ada、C、C++、Fortran、Ja
Linux C程式設計學習筆記(2):open、creat、close函式及檔案的建立、開啟與關閉
my_create.c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include
sqlite學習筆記7:C語言中使用sqlite之打開數據庫
實例 clas details code 返回 pri san filename stdlib.h 數據庫的基本內容前面都已經說得差點兒相同了。接下看看如何在C語言中使用sqlite。 一 接口 sqlite3_open(const char *filename, s
sqlite學習筆記11:C語言中使用sqlite之刪除記錄
false done mta ase rom real not null -a ubun 最後一節,這裏記錄下怎樣刪除數據。 前面全部的代碼都繼承在這裏了,在Ubuntu14.04和Mac10.9上親測通過。 #include <stdio.h> #in
sqlite學習筆記9:C語言中使用sqlite之插入數據
name article void num mes cut cpp content int 前面創建了一張表,如今給他插入一些數據。插入數據跟創建表差點兒相同,不過SQL語言不一樣而已,完整代碼例如以下: #include <stdio.h> #inclu
快速傅立葉變換FFT的學習筆記一:C語言程式碼的簡單實現
快速傅立葉變換FFT的學習筆記一:C語言程式碼的簡單實現 fft.c #include "math.h" #include "fft.h" void conjugate_complex(int n,complex in[],complex out[]) { int i = 0
C++11併發學習之二:執行緒管理
1.啟動執行緒 (1)使用物件 “小試牛刀”中thread構造時傳入的是函式,還可以傳入物件。 #include <thread> #include <iostream> void func() { std::cout<<
LDA主題模型學習筆記5:C原始碼理解
1,說明 本文對LDA原始論文的作者所提供的C程式碼中LDA的主要邏輯部分做註釋,原始碼可在這裡下載到:https://github.com/Blei-Lab/lda-c 這份程式碼實現論文《Latent Dirichlet Allocation》中介紹的LDA模型,用變分
C#學習筆記2:C#中修飾類相關的關鍵字
修飾符用於限定型別以及型別成員的申明,C#中的修飾符按功能可分為四部分:屬性修飾符,存取修飾符,類修飾符和成員修飾符。 屬性修飾符: [Serializable]:按值將物件封送到遠端伺服器。在按值封送物件時,就會建立一個該物件的副本,並將其序列化傳送到伺服器。 任何
C# 好程式碼學習筆記(1):檔案操作、讀取檔案、Debug/Trace 類、Conditional條件編譯、CLS
[TOC] 目錄: 1,檔案操作 2,Debug、Trace類 3,條件編譯 4,MethodImpl 特性 5,CLSComplianAttribute 6,必要時自定義類型別名 最近在閱讀 .NET Core Runtime 的原始碼,參考大佬的程式碼,學習編寫技巧和提高程式碼水平。學
nodejs學習筆記二:閉包和非同步程式設計
閉包到底是什麼鬼 閉包就是函式��,但是它可以繼承並訪問它自身被宣告的那個作用域裡的變數。當你將一個回撥函式作為引數傳遞給另外一個進行i/o操作的函式時,回撥函式稍後會被呼叫,神奇的是,在被呼叫時,回撥函式會記住它自身宣告時所在的上下文,並且可以訪問該上下文及
Qt5 學習筆記 二:UI 程式設計
既然說Qt最方便的是它的UI介面程式設計,那我們就從UI開發開始我們的Qt程式設計之旅。 個人原創,轉載請註明出處: http://blog.csdn.net/embbnux/article/details/
SpringMVC學習筆記二:常用註解
title c學習 請求 pin 學習 lin att 詳解 stp 轉載請註明原文地址:http://www.cnblogs.com/ygj0930/p/6831976.html 一、用於定義類的註解:@Controller @Controller 用於標記在一個類上,
framework7學習筆記二:基礎知識
部分 cnblogs query 基礎 logs code 自己 $$ pan 一:DOM7 framework7有自己的 DOM7 - 一個集成了大部分常用DOM操作的高性能庫。它的用法和jQuery幾乎是一樣的,包括大部分常用的方法和jquery風格的鏈式調用。 在開發