1. 程式人生 > >C ++ 指標 | 指標與函式、陣列_3

C ++ 指標 | 指標與函式、陣列_3

指標與函式

1、void 函式名(int *p)

#include<iostream>
using namespace std;

void Increment(int *p)
{
    *p = (*p) + 1;
}

int main()
{
    int a;
    a = 10;
    Increment(&a);
    cout << "a = " << a << "\n";
}

執行結果:

以上程式碼使用了 按值傳遞(Call by value) 技術。Increment(&a) 的裡面的 &a 對映到函式 Increment(int *p) 中的 int *p ,實際上就是:

int *p = &a;

2、

兩種陣列列印方式:

#include<iostream>

using namespace std;

int main()
{
    int A[] = {1,2,3,4,5,6};
    cout << "A = " << A << "\n";
    cout << "&A[0] = " << &A[0] << "\n";
    cout << "A[0] = " << A[0] << "\n";
    cout << "*A = " << *A << "\n";
}

執行結果:

3、

陣列的指標運算操作:

#include<iostream>

using namespace std;

int main()
{
    int A[] = {1,2,3,4,5};
    int i;
    for(i = 0;i<5;i++)
    {
        cout << "&A[i] = " << &A[i] << "\n";
        cout << "&A+i = " << A+i << "\n";
        cout << "A[i] = " << A[i] << "\n";
        cout << "*(A+i) = " << *(A+i) << "\n";
        cout << "====================" << "\n";
    }
}

執行結果:

4、

陣列作為函式引數:

#include<iostream>
using namespace std;

int SumOfElements(int A[], int size)
{
    int i, sum = 0;
    for(i=0;i<size;i++)
    {
        sum+=A[i];
    }
    return sum;
}

int main()
{
    int A[] = {1,2,3,4,5};
    int size = sizeof(A)/sizeof(A[0]);
    int total = SumOfElements(A, size);
    cout << "Sum of elements = " << total <<"\n";
    return 0;
}

執行結果:

我們試用不同的方法,

以上程式碼的 mian() 函式下,獲取了陣列的長度 除以 1,也就是陣列的長度。

下面我們不在主函式獲取程式碼,而是去SumOfElements函式 獲取陣列的長度:

#include<iostream>
using namespace std;

int SumOfElements(int A[])
{
    int i, sum = 0;
    int size = sizeof(A)/sizeof(A[0]);
    for(i=0;i<size;i++)
    {
        sum+=A[i];
    }
    return sum;
}

int main()
{
    int A[] = {1,2,3,4,5};
    int total = SumOfElements(A);
    cout << "Sum of elements = " << total <<"\n";
    return 0;
}

執行結果:

兩次執行結果不是應該一樣的嗎?為什麼?我們 打印出 A 和 A[0]的值:

#include<iostream>
using namespace std;

int SumOfElements(int A[])
{
    int i, sum = 0;
    int size = sizeof(A)/sizeof(A[0]);

    cout << "size of A: " << sizeof(A) << "\n";
    cout << "size of A[0]: " << sizeof(A[0]) << "\n";

    for(i=0;i<size;i++)
    {
        sum+=A[i];
    }
    return sum;
}

int main()
{
    int A[] = {1,2,3,4,5};
    int total = SumOfElements(A);
//    cout << "Sum of elements = " << total <<"\n";
    cout << "size of A: " << sizeof(A) << "\n";
    cout << "size of A[0]: " << sizeof(A[0]) << "\n";
    return 0;
}

執行結果:

為什麼主函式的A的大小為20,S函式的A的大小為8?我們需要深入研究編譯器是怎麼編譯一個數組作為函式引數。圖1,假如這塊是記憶體,執行main()函式,記憶體會拿出一塊stack型別的記憶體來儲存main()函式下的區域性變數:

如圖2,然後main()執行到SOE()函式的時候,記憶體會畫出新的空間來儲存SOE()函式下的引數int A[],然後我們的想法就是把int A[] = {1,2,3,4,5} 賦值給 SOE()函式的引數 int A[]。可是,C語言不會這麼做的。

當編譯器看到函式的引數時,它不會複製整個陣列!實際上是做什麼呢?如圖3,它只是建立了名稱相同的指標變數,而不是建立整個陣列,它只是建立了一個指標。指標指向整型的數字的指標。並且編譯器只是複製了陣列中的第一個元素的地址。

圖4:起始地址是第一個元素的地址,在這個陣列A中屬於main方法是200:。所以接下來就好理解了。

int SumOfElements(int A[])

這裡的引數 int A[] ,編譯器隱式的轉換它為  int* A,引數只取陣列的前4個位元組或者8個位元組。

注意:int* A  和 int *A一樣。一般會這樣寫:int* A 。

為什麼C的編譯器要這麼做呢??

答:陣列的大小可能非常大,因此建立新陣列沒有多大意義,每次不必要地使用大量記憶體時,就會很浪費系統資源。

所以,寫C/C++程式的時候,最節省記憶體的寫法還是直接在 mian()函式 就獲取陣列的長度。

#include<iostream>
using namespace std;

int SumOfElements(int* A, int size)
{
    int i, sum = 0;

    for(i=0;i<size;i++)
    {
        sum+=A[i];
    }
    return sum;
}

int main()
{
    int A[] = {1,2,3,4,5};
    int size = sizeof(A)/sizeof(A[0]);
    int total = SumOfElements(&A[0], size);

    cout << "Sum of elements = " << total <<"\n";
    cout << "size of A: " << sizeof(A) << "\n";
    cout << "size of A[0]: " << sizeof(A[0]) << "\n";
    return 0;
}

執行結果:

注意:(1)

int total = SumOfElements(&A[0], size);

這裡使用了 &A[0] 也是可以的,它會 A[0] 到 A[4] 的值全部加起來。

如果是 &A[1] ,它會 A[1] 到 A[4] 的值全部加起來。

(2)當 A 是一個數組,不能做遞增或遞減。

(3)A[ i ] 等價於 *( A + i ) 。這就是為什麼 int total = SumOfElements(&A[0], size); 裡面的引數輸入&A[0],能夠列印陣列的所有值。

以上這些都需要記住的。

現在我們讓 A[] = {1,2,3,4,5} 每個值乘以2:

#include<iostream>
using namespace std;

void Double(int* A, int size)
{
    int i, sum = 0;
    for(i = 0;i < size; i++)
    {
        A[i] = 2 * A[i];
    }
}

int main()
{
    int A[] = {1,2,3,4,5};
    int size = sizeof(A)/sizeof(A[0]);
    int i;
    Double(A, size);
    for(i = 0; i < size; i++)
    {
        cout << "A["<<i<<"]"<<A[i]<<"\n";
    }
    return 0;
}

執行結果:


演算法和資料結構就是程式設計的一個重要部分,你若失掉了演算法和資料結構,你就把一切都失掉了。