1. 程式人生 > >詳談C++中陣列作為函式引數

詳談C++中陣列作為函式引數

一、一個例子引發的思考

  執行以下程式碼,請問輸出是什麼?例子來源於《劍指Offer》,我對書上例子做了修改,讓其可以執行。

#include<iostream>
using namespace std;

int GetSize(int data[]) {
    return sizeof(data);
}
int main() {
    int data1[] = {1,2,3,4,5};
    int size1 = sizeof(data1);

    int *data2 = data1;
    int size2 = sizeof(data2);

    int
size3 = GetSize(data1); cout<<size1<<" "<<size2<<" "<<size3<<endl; return 0; }

執行結果如下:
這裡寫圖片描述
  data1是一個數組,sizeof(data1)是求陣列的大小。這個陣列包含5個整數,每個整數佔4個位元組,因為總共是20個位元組。data2宣告為指標,儘管它指向了陣列data1,對認真指標求sizeof,得到的結果都是4。在C/C++中,當陣列作為函式的引數進行傳遞時,陣列就自動退化為同類型的指標。因此儘管函式GetSize的引數data被宣告為陣列,但它會退化為指標,size3的結果仍然是4.

二、陣列的兩個特殊性質

(1)不允許拷貝和賦值

  不能將陣列的內容拷貝給其他陣列作為其初始值,也不能用陣列為其他陣列賦值。

int a[] = {0,1,2};    // 含有三個整數的陣列
int s2 = a;           // 錯誤:不允許使用一個數組初始化另一個數組
a2 = a;               // 錯誤:不能把一個數組直接賦值給另一個數組

(2)使用陣列是通常將其轉化成指標

  在C++語言中,指標和陣列有非常緊密的聯絡。使用陣列的時候編譯器一般會把它轉換成指標。

  通常情況下,使用取地址符來獲取指向某個物件的指標,取地址符也可以用於任何物件。陣列的元素也是物件,對陣列使用下標運算子得到該陣列指定位置的元素。因此像其他物件一樣,對陣列的元素使用取地址符就能的搭配指向該元素的指標:

string nums[] = {"one", "two", "three"};  // 陣列元素是string物件
string *p = &nums[0];                     // p指向nums的第一個元素

  然而,陣列還有一個特性:在很多用到陣列名字的地方,編譯器都會自動地將其替換為一個指向陣列首元素的指標:

string *p2 = nums;                        // 等價於p2 = &nums[0]

  在大多數表示式中,使用陣列型別的物件其實是使用一個指向該陣列首元素的指標。

三、陣列形參

  陣列的兩個特殊性質對我們定義和使用作用在陣列上的函式有影響。因為不能拷貝陣列,所以我們無法以值傳遞的方式使用陣列引數。因為陣列會被轉換成指標,所以當我們為函式傳遞一個數組時,實際上傳遞的是指向陣列首元素的指標。
  儘管不能以值傳遞的方式傳毒陣列,但是我們可以把形參寫成類似陣列的形式:

//儘管形式不同,但這三個print函式是等價的
//每個函式都有一個const int*型別的形參
void print(const int*);
void print(const int[]);
//這裡的維度表示我們期望陣列含有多少元素,實際不一定
void print(const int[10]); 

  儘管表現形式不同,但上面的三個函式是等價的:每個函式的唯一形式都是const int*型別的。當編譯器處理對print函式的呼叫時,只檢查傳入的引數是否是const int*型別:

int i=0,j[2] = {0,1};
print(&i);               //正確:&i的型別是int*
print(j);                 //正確:j轉船成int* 並指向j[0]

  如果我們傳給print函式的是一個數組,則實參自動地轉換成指向陣列首元素的指標,陣列的大小對函式的呼叫沒有影響。

  和其他使用陣列的程式碼一樣,以陣列作為形參的函式也必須確保使用陣列時不會越界。

相關推薦

詳談C++陣列作為函式引數

一、一個例子引發的思考   執行以下程式碼,請問輸出是什麼?例子來源於《劍指Offer》,我對書上例子做了修改,讓其可以執行。 #include<iostream> using namespace std; int GetSize(int da

C++陣列作為函式引數或返回值

C++中陣列作為函式引數或者返回值 概述 在程式設計任務中,經常會遇到將陣列作為函式引數或者返回值,比如在前一篇的計數排序任務中,需要額外的空間來儲存排序後的元素,並且將該陣列返回給主函式。本文會介紹幾種可行的方案,僅供參考。 陣

C語言如何將陣列作為函式引數傳遞

今天覆習到c語言的陣列,看到這麼一個問題: 現在,你的程式要讀入兩個多項式,然後輸出這兩個多項式的和,也就是把對應的冪上的係數相加然後輸出。 程式要處理的冪最大為100。 輸入格式: 總共要輸入兩個多項式,每個多項式的輸入格式如下: 每行輸入兩個數字,第一個表

C++多維陣列作為函式引數該怎麼寫?

眾所周知,函式引數中一維陣列的長度會被忽略的,但二維陣列的第二維度就會被要求指定長度(否則gcc會報告“陣列元素的型別不完全”)。這很好理解,它是為了讓函式知道矩陣的寬度。同理,三維陣列就會被要求指定第二維度和第三維度的長度,所以n維陣列只有第一維度的長度會被忽略。那麼對於

二維陣列作為函式引數傳遞(C++)

有時候我們也許會不明白為什麼C++中的陣列宣告的時候下標是需要一個常數,而不能是一個變數吶?也許STL模板庫中的向量可以解決變數作為下標的陣列宣告方式,為了節約一些記憶體或者是提高一些效能,也為了功能不重複,故而陣列中的下標採取了常量的方式。 int a[

強化C陣列作為函式引數-多維陣列的本質

#include <stdio.h> #include <stdlib.h> #include <string.h> //多維陣列的本質就是一個指標陣列,由於多維

C++基礎知識複習--結構體類陣列作為函式引數

//結構體陣列,類陣列,普通陣列,作為函式引數 #include<iostream> #include<string> using namespace std; class C

二維陣列作為函式引數

https://www.cnblogs.com/alantu2018/p/8465894.html   1、二維陣列的概念   在C語言中,二維陣列實際上是一種特殊的一維陣列,它的每個元素也是一個一維陣列。因此,二維陣列下標形式正確寫法如下:int arrays[i][j]。陣

C語言指標作為函式引數傳遞學習(一)

1. 一維指標做函式引數 傳入的指標為NULL 比如下面的例子,很多人都會理解錯: #include <stdio.h> void test(char *string) { string = "hello world"; } int main() { cha

結構體陣列作為函式引數

把結構體陣列名作為函式的一個引數,然後在這個函式的函式裡面繼續作為引數,把一個值賦給這個結構體陣列的一個變數,我再賦值的地方是有值的,在函式裡面也是有值的,但是出了這個函式回到主函式時,這個結構體陣列的變數的值就為空了。為什麼呢?因為我在使用這個函式是這樣的, iRetur

有關 陣列作為函式引數 & 區域性變數和全域性變數及其應用

一、陣列blabla 1.0陣列元素作函式實參。 (1).陣列元素可以用作函式實參,但不能是形參。(給陣列分配的儲存單元是連續的) 2.0一維陣列名作函式引數。 (1)陣列元素作實參時,向形參變數傳遞的時陣列元素的值。 陣列名作實參時,向形參傳遞的時陣列首元素的地址。

java 11:陣列作為函式引數陣列做為函式返回值

1 陣列作為引數 我們可以將陣列作為引數,傳入到函式中,其實就像我們main函式中 public void main(String [] args){};就是用陣列作為函式引數; 又如, publicclass ArrayPar  {  publicstaticvoid

c++之指標作為函式引數傳遞的問題

轉自:http://blog.csdn.net/fjb2080/article/details/5623427   原創文章,轉載請註明出處,謝謝! 作者:清林,部落格名:飛空靜渡   部落格地址:http://blog.csdn.net/fjb2080 &n

C++陣列作為形參時,實際傳的是指標

傳陣列時,實際上是建立了臨時的指標變數,指向傳進去的那個陣列。在函式中改變形引數組(臨時指標變數)的指向是可以的,只不過這樣做不會改變原來的陣列 //例子說明陣列做形參時,實際上是用一個臨時指標變數做形參,指向傳進去的陣列首地址。實際的陣列是常指標,不能改變它的值。 #i

Go語言切片作為函式引數函式使用append新增元素

切片作為函式,通過append新增元素,有可能會更改地址: 1)新增的資料元素長度超過切片引數的容量,則會另開闢空間,重新分配底層陣列,並複製資料。函式中的此切片與原切片地          址不同; 此切片指向新開闢的記憶體。函式執行結束,記憶體釋放,不會影響元切片的內容。

陣列作為函式引數傳遞

陣列有兩個特殊的性質。一是不能複製陣列;二是使用陣列名字時,陣列會自動轉化為指向其第一個元素的指標。由於陣列不能複製,所以無法編寫使用陣列型別形參的函式,因為陣列會被自動轉化為指標。 一、一維陣列 1.三種定義形式: void printvalues(int *); vo

多維陣列作為函式引數的形式

int *matvec4(int *A, int *x, int n){ int i,j; int *y = Malloc(n * sizeof(int)); for(i=0; i<n ;i++) y[i] = 0; for(i=0; i<n;

C++引用(作為函式引數和返回值)

一、引用簡介 引用就是某一變數(目標)的一個別名,對引用的操作與對變數直接操作完全一樣。 引用的宣告方法:型別識別符號 &引用名=目標變數名; eg:int a; int &b=

C語言 陣列函式引數

看下面程式碼:int main() { int a[5]={3,6,4,2,5}; char *ptrChar="hello world";//ptrChar是char型別的指標,指向記憶體空間 int *ptrInt=a;//ptrInt是指向int型別的指標 p

C++ 有關指標作為函式引數的問題,自定義記憶體分配函式傳遞二級指標的問題

如題所示,我們主要討論在自定義的記憶體分配函式中通常見到的程式碼如下所示: ``` void Create(A** addr); ``` 其中傳遞的引數是二級指標。為什麼? 我們先看一下完整的動態記憶體分配函式的簡單例子: ``` struct A { int a = 0; int b = 0