第35課配列パラメータとポインタパラメータ分析
2084 ワード
退化の意味
C言語では値コピーのみでパラメータが渡されます
関数に配列を渡すとき:
配列名を定数ポインタと見なして配列ヘッダ要素アドレスを渡す
C言語は効率を最初の設計目標とする:
aパラメータ伝達時に配列全体をコピーすると実行効率が大幅に低下し、bパラメータがスタック上に存在し、配列コピーが大きすぎるとスタックオーバーフローを引き起こす
2 D配列パラメータ
2 D配列パラメータにも劣化の問題がある
2 D配列は、1 D配列と見なすことができます.2 D配列の各要素は1 D配列です.
2 D配列パラメータの1 D目のパラメータは省略できます
void f(int a[5]) ←→ void f(int a[]) ←→ void f(int *a)void g(int a3) ←→ void g(int a[][3]) ←→ void g(int *a[3])
等価関係
配列パラメータ
等価なポインタパラメータ
一次元配列:float a[5]
ポインタ:float*a
ポインタ配列:int*a[5]
ポインタのポインタ:int**a
2 D配列:char a[3]
配列のポインタ:char(*a)[4]
C言語では1つの関数に任意の多次元配列を渡すことができない
次元以外のすべての次元の長さを指定する必要があります
第1次元以外の次元情報ポインタ演算を完了するためのN次元配列の本質は1次元配列であり、要素はN−1次元の配列であり、多次元配列に対する関数パラメータは第1次元のみが可変である例35−1である.
出力結果:sizeof(a)=4 sizeof(*a)=12012345678 sizeof(b)=4 sizeof(*b)=2400000
まとめ:C言語で1値コピーしかできない方法でパラメータを渡すC言語の配列パラメータは必然的にポインタ多次元配列パラメータに劣化します.ポインタ多次元配列パラメータは、1次元以外のすべての次元長を提供する必要があります.多次元配列の関数パラメータは、1次元のみが可変です.
C言語では値コピーのみでパラメータが渡されます
関数に配列を渡すとき:
配列名を定数ポインタと見なして配列ヘッダ要素アドレスを渡す
C言語は効率を最初の設計目標とする:
aパラメータ伝達時に配列全体をコピーすると実行効率が大幅に低下し、bパラメータがスタック上に存在し、配列コピーが大きすぎるとスタックオーバーフローを引き起こす
2 D配列パラメータ
2 D配列パラメータにも劣化の問題がある
2 D配列は、1 D配列と見なすことができます.2 D配列の各要素は1 D配列です.
2 D配列パラメータの1 D目のパラメータは省略できます
void f(int a[5]) ←→ void f(int a[]) ←→ void f(int *a)void g(int a3) ←→ void g(int a[][3]) ←→ void g(int *a[3])
等価関係
配列パラメータ
等価なポインタパラメータ
一次元配列:float a[5]
ポインタ:float*a
ポインタ配列:int*a[5]
ポインタのポインタ:int**a
2 D配列:char a[3]
配列のポインタ:char(*a)[4]
C言語では1つの関数に任意の多次元配列を渡すことができない
次元以外のすべての次元の長さを指定する必要があります
第1次元以外の次元情報ポインタ演算を完了するためのN次元配列の本質は1次元配列であり、要素はN−1次元の配列であり、多次元配列に対する関数パラメータは第1次元のみが可変である例35−1である.
#include "stdio.h"
void access(int a[][3],int row)
{
int col = sizeof(*a)/sizeof(int); //
int i = 0;
int j = 0;
int k = 0;
printf("sizeof(a) = %d
",sizeof(a));
printf("sizeof(*a) = %d
",sizeof(*a));
for(i = 0;i < row;i ++)
{
for(j = 0;j < col;j ++)
{
printf("%d
",a[i][j]);
}
}
printf("
");
}
void access_ex(int b[][2][3],int n)
{
int i = 0;
int j = 0;
int k = 0;
printf("sizeof(b) = %d
",sizeof(b));
printf("sizeof(*b) = %d
",sizeof(*b));//int[2][3] ==> 24
for(i = 0;i < n; i++)
{
for(j = 0;j < 2;j++)
{
for(k = 0;k <3;k ++)
{
printf("%d
",b[i][j][k]);
}
}
}
printf("
");
}
int main()
{
int a[3][3] = {{0,1,2},{3,4,5},{6,7,8}};
int aa[2][2] = {0};
int b[1][2][3] = {0};
access(a,3);
//access(aa,2);
access_ex(b,1);
//access_ex(aa,2);//
}
出力結果:sizeof(a)=4 sizeof(*a)=12012345678 sizeof(b)=4 sizeof(*b)=2400000
まとめ:C言語で1値コピーしかできない方法でパラメータを渡すC言語の配列パラメータは必然的にポインタ多次元配列パラメータに劣化します.ポインタ多次元配列パラメータは、1次元以外のすべての次元長を提供する必要があります.多次元配列の関数パラメータは、1次元のみが可変です.