1. 程式人生 > >C/C++程式設計學習筆記二:C語言的函式中,如何使用指標交換兩個數的值,深入理解指標

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學習筆記7C語言使用sqlite之打開數據庫

實例 clas details code 返回 pri san filename stdlib.h 數據庫的基本內容前面都已經說得差點兒相同了。接下看看如何在C語言中使用sqlite。 一 接口 sqlite3_open(const char *filename, s

sqlite學習筆記11C語言使用sqlite之刪除記錄

false done mta ase rom real not null -a ubun 最後一節,這裏記錄下怎樣刪除數據。 前面全部的代碼都繼承在這裏了,在Ubuntu14.04和Mac10.9上親測通過。 #include <stdio.h> #in

sqlite學習筆記9C語言使用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主題模型學習筆記5C原始碼理解

1,說明 本文對LDA原始論文的作者所提供的C程式碼中LDA的主要邏輯部分做註釋,原始碼可在這裡下載到:https://github.com/Blei-Lab/lda-c 這份程式碼實現論文《Latent Dirichlet Allocation》中介紹的LDA模型,用變分

C#學習筆記2C#修飾類相關的關鍵字

修飾符用於限定型別以及型別成員的申明,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風格的鏈式調用。 在開發