C語言陣列作為函式引數
文章目錄
- 一:陣列元素作為函式的實參
- 二:陣列名作為函式的實參
- 關于陣列作為函式引數呼叫的討論
- 關于函式定義的引數表的討論
- 三:二維陣列名作為函式引數
- 獲取二維陣列的行和列
- 四:更高維陣列作為函式引數同二維陣列類似
- 五:參考檔案
一:陣列元素作為函式的實參
陣列元素就是變數,與普通變數沒有區別,將陣列元素傳送給形參,實作單向的值傳遞, 用陣列元素作實參時,只要陣列型別和函式的形參變數的型別一致,那么作為下標變數的陣列元素的型別也和函式形參變數的型別是一致的, 因此,并不要求函式的形參也是下標變數,換句話說,對陣列元素的處理是按普通變數對待的, 在普通變數或下標變數作函式引數時,形參變數和實參變數是由編譯系統分配的兩個不同的記憶體單元,在函式呼叫時發生的值傳送是把實參變數的值賦予形參變數,
#include <stdio.h>
float max(float x,float y)
{
if(x > y)
return x;
else
return y;
}
int main()
{
int a[6] = {3,2,1,4,9,0};
int m = a[0];
for(int i = 1;i < 6; i ++)
{
m = max(m,a[i]);
}
printf("陣列中的最大元素是:%d",m);
}
二:陣列名作為函式的實參
實質是地址的傳遞,將陣列的首地址傳給形參,形參和實參共用同一存盤空間,形參的變化就是實參的變化,用陣列名作函式引數時,則要求形參和相對應的實參都必須是型別相同的陣列,都必須有明確的陣列說明,當形參和實參二者不一致時,即會發生錯誤,在用陣列名作函式引數時,不是進行值的傳送,即不是把實引陣列的每一個元素的值都賦予形引陣列的各個元素,因為實際上形引陣列并不存在,編譯系統不為形引陣列分配記憶體,
那么,資料的傳送是如何實作的呢?
在我們曾介紹過,陣列名就是陣列的首地址,因此在陣列名作函式引數時所進行的傳送只是地址的傳送,也就是說把實引陣列的首地址賦予形引陣列名,形引陣列名取得該首地址之后,也就等于有了實在的陣列,實際上是形引陣列和實引陣列為同一陣列,共同擁有一段記憶體空間,
舉例子:

上圖說明了這種情形,圖中設a為實引陣列,型別為整型,a占有以2000為首地址的一塊記憶體區,b為形引陣列名,當發生函式呼叫時,進行地址傳送,把實引陣列a的首地址傳送給形引陣列名b,于是b也取得該地址2000,于是a,b兩陣列共同占有以2000為首地址的一段連續記憶體單元,從圖中還可以看出a和b下標相同的元素實際上也占相同的兩個記憶體單元(整型陣列每個元素占二位元組),例如a[0]和b[0]都占用2000和2001單元,當然a[0]等于b[0],類推則有a[i]等于b[i],
舉例說明,同時練習冒泡排序,小的數像水泡浮在上面,
#include <stdio.h>
//其中形引陣列b沒有給出長度,而由n值動態地表示陣列的長度,n的值由主調函式的實參進行傳送,
void sort(int b[], int n)
{
for (int i=0;i<n-1;i++)//n個數比較只需要比較n-1次,因為比較是兩個數之間進行的,比如兩個數比較只需要比較1次,
{
for (int j = 0; j < n - 1 - i; j++)
//可以這么理解當大的數沉底后,就不再參與排序了,回圈1次,找出此輪中最大的數放在該輪比較的最底部,
//下一輪找出剩下資料中的最大值,并排到該輪最底部,排序了i次后,就有i個數退出排序,就只剩下n-1-i個數待排,這就是n-1-i的由來
{
if (b[j] > b[j + 1])
{
int temp = 0;
temp = b[j];
b[j] = b[j + 1];
b[j + 1] = temp;
}
}
}
}
int main()
{
int a[6] = { 3,2,1,4,9,0 };
sort(&a[0], sizeof(a) / sizeof(a[0]));
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
{
printf("%d ", a[i]);
}
return 0;
}
關于陣列作為函式引數呼叫的討論
其中陣列作為函式引數呼叫還可以寫成如下形式:
sort(a, sizeof(a) / sizeof(a[0]));
sort(&a[0], sizeof(a) / sizeof(a[0]));
測驗結果:

關于函式定義的引數表的討論
另外函式定義的引數表可以寫成:
void sort(int b[], int n);
void sort(int b[x], int n); //其中x≠0即可
其中x≠0即可,實際編程中寫成這樣也沒必要,直接用void sort(int b[], int n)就行,
測驗:
x=1 小于a的陣列長度

x=100 大于a的陣列長度

但是當x為0時,編譯都無法進行:

三:二維陣列名作為函式引數
第一維的大小可以不指定,第二維的大小必須指定,實參傳送的是二維陣列的首地址,使得二維陣列a與b共用同一存盤單元,即a[0][0]與b[0][0]共用同一存盤單元,a[0][1]與b[0][1]共用同一存盤單元,
測驗:
#include <stdio.h>
//b[2][3]也正確
int max(int b[][3])
{
int m = 0;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
if (m < b[i][j])
{
m = b[i][j];
}
}
}
return m;
}
int main()
{
int a[2][3] = { 3,2,1,4,9,0 };
int sizea = sizeof(a);
int maxVal = max(a);
printf("max is %d ", maxVal);
return 0;
}

注意形參二維陣列的第二維必須與實參一致,否則會報錯,如下圖所示:

第一維除了不能為0以外,都可以,實際編程中直接與實參的維度一樣,沒必要制造麻煩,


獲取二維陣列的行和列
獲取二維陣列的行和列是經常遇到的
定義一個二維陣列int array[A][B],可以通過計算sizeof獲取行列數,
sizeof(array[0][0])為一個元素占用的空間,
sizeof(array[0])為一行元素占用的空間,
sizeof(array)為整個陣列占用的空間,
行數 = sizeof(array)/sizeof(array[0]);
列數 = sizeof(array[0])/sizeof(array[0][0]);
根本原因:
測驗:

四:更高維陣列作為函式引數同二維陣列類似
舉例
#include "conv1.h"
#include <iostream>
#include <iomanip>
using namespace std;
float max(const float conv1_weight[64][3][3][3][3]);
int main()
{
int a[2][3] = { 0,1,2,
3,4,5 };
cout << a[1][2] << endl;
cout << "numbers of conv1_weight: " << sizeof(conv1_weight) / sizeof(conv1_weight[63][2][2][2][2]) << endl;
cout << "conv1_weight[63][2][2][2][2]: " << setiosflags(ios::fixed) << setprecision(10) << conv1_weight[63][2][2][2][2] << endl;
cout << "max of conv1_weight: " << max(conv1_weight) << endl;
int b = 16;
b >>= 1;
cout << b;
return 0;
}
float max(const float conv1_weight[64][3][3][3][3])
{
float max = 0;
for (int i = 0; i < 64; i++)
for (int j = 0; j < 3; j++)
for (int k = 0; k < 3; k++)
for (int m = 0; m < 3; m++)
for (int n = 0; n < 3; n++)
{
if (max < conv1_weight[i][j][k][m][n])
{
max = conv1_weight[i][j][k][m][n];
}
}
return max;
}
其中conv1_weight[64][3][3][3][3]為下圖所示:
測驗結果:

五:參考檔案
http://c.biancheng.net/cpp/html/61.html
https://blog.csdn.net/lishundi/article/details/87906920
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/263474.html
標籤:其他
上一篇:安卓第四趴


