第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である.
#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次元のみが可変です.