目次
一次元配列
- 説明形式:タイプ識別子[式];
- アクセス配列:(1)添え字形式;(2)ポインター形式。2つの方法の例は次のとおりです。
/**********************************************************
* 函数:AccessArray
* 描述:访问数组的方式
* 参数:无
* 返回:无
* 备注:1.下标 2.指针形式
**********************************************************/
void AccessArray(void)
{
int i;
int* p;
static int a[5] = {
1,2,3,4,5 };//定义一个静态的int类型数组
//下标访问
cout << "以下标方式访问数组" << endl;
for (i = 0; i < 5; i++)
{
cout << "a[" << i << "]=" << a[i] << " ";
}
cout << endl;
//指针形式访问-1
cout << "以指针方式访问数组-1" << endl;
for (i = 0; i < 5; i++)
{
cout << "a[" << i << "]=" << *(a+i) << " ";
}
cout << endl;
//指针形式访问-2
cout << "以指针方式访问数组-2" << endl;
p = a;
for (i = 0; i < 5; p++,i++)
{
cout << "a[" << i << "]=" << *p << " ";
}
cout << endl;
//数组元素的地址
cout << "数组元素的地址:" << endl;
p = a;
for (i = 0; i < 5; p++, i++)
{
cout << "a[" << i << "]的地址:" << p << endl;
}
}
演算結果:
1。配列名aは定数a ==&a [0]であるため、自己加算a ++は実行できず、その値は同じのポインタ変数にのみ割り当てることができます。タイプ* p、pは単独で追加できます。そのようなポインタ変数がない場合は、*(a + i)の形式でのみアクセスできます。2.配列の各要素のアドレスから、各要素のアドレスにはsizeof(int)= 4の差があり、メモリ内の1次元グループ要素の配置は連続しており、各要素のアドレスの違いは、その要素タイプが占めるスペースのサイズに等しくなります。3.コンパイラは、配列アクセスが制限を超えているかどうかをチェックしませんので、注意してください。
ポインタ配列
定義
説明形式:タイプ*識別子[式];例:
int * pi [3];
char * pf [5];
ポインター配列とint型などの基本型の配列の違いは、配列の型が格納されるものが異なり、格納されるのはポインタ型です。
注:int * pi [3]はint(* pi)[3]として記述できません。piinint* pi [3]はポインターの配列ですが、
pi in int(* pi)[3]はへのポインターです。 1次元配列(長さ3)ポインター。記号の優先度によって説明できます。int* pi [3]では、[]記号の優先度が*記号よりも高いため、[]は最初にpiと結合され、piは最初に配列であり、次に左側と組み合わせると、配列要素のデータ型がint *であることを示します。int(* pi)[3]の場合、()記号の優先度は[]記号の優先度よりも高いため、*は最初にpiと組み合わせると、piはポインタintであり、[3]ポインタに関連付けられた配列の型は3長整数型の1次元配列であることを説明します。
基本的な配列型へのポインタの配列
int、char、その他のデータ型などの基本データ型上記のint * pi [3]は、基本配列型へのポインタの配列です。名前が示すように、基本データ型のアドレス(ポインタ)はに格納されます。配列。このタイプの配列は、変数アドレスを管理するために使用できます。
配列へのポインタの配列
これは、配列へのポインタの配列に例えることができます。つまり、他の配列へのポインタは内部に格納されますが、これらの配列のタイプは同じである必要がありますが、長さは同じである必要はありません。実際、「基本的な配列型へのポインタの配列」は「配列へのポインタの配列」の特殊なケースと見なすことができます。「配列へのポインタの配列」の配列の長さが1および=の場合、次のようになります。 「基本的な配列タイプを指す」「ポインタ配列」と見なされます。「基本的な配列型へのポインタの配列」には、配列の各メンバーにアクセスできる配列アドレスが格納されています。例は次のとおりです。
/**********************************************************
- 函数:PointerArray_PointArray
- 描述:指向数组的指针数组
- 参数:无
- 返回:无
- 备注:
**********************************************************/
void PointerArray_PointArray(void)
{
int a[2] = {
1,2 };
int b[3] = {
3,4,5 };
int c[4] = {
6,7,8,9 };
int* pi[3] = {
a,b,c };//数组名就是数组的地址
int i;
//访问数组a
cout << "访问数组a" << endl;
for (i = 0; i < 2; i++)
{
cout << "a[" << i << "]=" << *(pi[0]+i) << " ";
}
cout << endl;
//访问数组b
cout << "访问数组b" << endl;
for (i = 0; i < 3; i++)
{
cout << "b[" << i << "]=" << *(pi[1] + i) << " ";
}
cout << endl;
//访问数组c
cout << "访问数组c" << endl;
for (i = 0; i < 4; i++)
{
cout << "c[" << i << "]=" << *(pi[2] + i) << " ";
}
cout << endl;
}
演算結果:
関数へのポインタの配列
また、関数へのポインタの配列に例えることもできます。つまり、関数ポインタ(関数ポインタ)は、関数のエントリアドレスである配列に格納され、関数は関数ポインタを介して呼び出すことができます。また、関数には関数名=関数ポインタ=関数アドレスがあるため、関数名を配列に直接格納することも、&関数名を使用することもできます。これらはすべて同じです。
定義
- typedefを使用して、最初に関数型を定義してから、配列を定義します。
例:typedef int FuncType(int、int); FuncType * pFunc [3];
これは、FuncType型関数へのポインターの配列を定義します。 - 直接定義し、次のように上記に従います:int(* pFunc [3])(int、int)。
- 定義後に配列を初期化します。
例
/**********************************************************
* 函数:PointerArray_PointFunc
* 描述:指向函数的指针数组
* 参数:无
* 返回:无
* 备注:
**********************************************************/
void PointerArray_PointFunc(void)
{
int i;
FuncType* PFunc[3] = {
f1,f2,f3};
for (i = 0; i < 3; i++)
{
PFunc[i]();//也可以写成(*PFunc[i])();
}
}
/**********************************************************
* 函数:f1
* 描述:函数1
* 参数:无
* 返回:无
* 备注:调用时打印“调用函数f1”
**********************************************************/
void f1(void)
{
cout << "调用函数f1" << endl;
}
/**********************************************************
* 函数:f2
* 描述:函数2
* 参数:无
* 返回:无
* 备注:调用时打印“调用函数f2”
**********************************************************/
void f2(void)
{
cout << "调用函数f2" << endl;
}
/**********************************************************
* 函数:f3
* 描述:函数1
* 参数:无
* 返回:无
* 备注:调用时打印“调用函数f3”
**********************************************************/
void f3(void)
{
cout << "调用函数f3" << endl;
}
//指向函数的指针数组
typedef void FuncType(void);
FuncType f1, f2, f3;
void PointerArray_PointFunc(void);
main関数でPointerArray_PointFunc関数を呼び出すと、結果は次のようになります。
二次元配列
定義と初期化
- 説明形式:タイプ配列名[式1] [式2];
式1:マトリックス内の行と見なすことができる第1次元
の長さ;式2:と見なすことができる第2次元の長さマトリックスの列として; - 初期化:最大寸法の説明は省略できます。といった:
- int a [2] [3] = { {1,2,3}、{4,5,6}};
- int a [2] [3] = {1,2,3,4,5,6};
- int a [2] [3] = { {1,2,3}、{4,5}}; //部分的な要素の初期化
- int a [] [3] = { {1,2,3}、{4,5,6}}; //最大寸法の説明を省略
アクセス
- 2次元配列へのアクセスには、添え字アクセスとポインタアクセスの2つの形式もあります。
- 添え字アクセスの理解は比較的簡単であり、ポインターのアクセスを理解する前に、そのような要約を知っているか理解する必要があります。配列構造は再帰的であり、n次元配列の各要素はn-1次元配列です。1次元配列は、多次元配列の特殊なケースとして理解できます。1次元配列へのポインターアクセスを理解するには、2次元配列へのポインターアクセスを理解する方が簡単です。
- (1)まず、1次元配列の配列名は定数ポインターであるため、割り当てることができず、int a [3]、aなどの最初の要素のアドレスと同じです。 ==&a [0]。int a [2] [3]、a ==&a [0]などの2次元配列と同様に、記述は同じですが、意味が異なります。1次元配列の場合、a [0]はint型の要素であり、2次元配列の場合、a [0]は配列を表します。これはn次元配列に類推できます。a[0]はn-1次元配列を表します。したがって、ポインタとしてのaは、異なる次元の配列の場合、関連付けられたタイプが異なります。n次元の配列の場合、aはn-1次元の配列に関連付けられます。実際、n次元配列の各要素にはn-1次元配列の配列名が格納され、n-1次元配列の各要素にはn-2次元配列の配列名が格納されることが簡単に理解できます。 。これは再帰的に続き、最後にプッシュします。1次元配列の場合は停止します。
(2)1次元配列では、a + i ==&a [i]は2次元配列でも有効ですが、(1)で説明したように意味が異なります。1次元配列では、隣接する各要素のアドレスオフセットはsizeof(type)であり、2次元配列では、隣接する要素のオフセットは(sizeof(type)* 1次元配列の長さ)であり、これが拡張されます。 n次元配列の場合、オフセットは(sizeof(type)* n-1次元配列内の要素の数)です。 - ポインタアクセスと添え字アクセスの例は次のとおりです。
/**********************************************************
* 函数:TwodimensionalArray
* 描述:二维数组
* 参数:无
* 返回:无
* 备注:二维数组定义与访问示例
**********************************************************/
void TwodimensionalArray(void)
{
int a[2][3] = {
{
1,2,3},{
4,5,6} };
int i,j;
int(*p)[3];//定义一个关联类型为长度为3的整形数组的指针
//各个元素的地址
cout << "各个元素的地址" << endl;
for (i = 0; i < 2; i++)
{
for (j = 0; j < 3; j++)
{
cout << "a[" << i << "]" << "[" << j << "]地址:" << &a[i][j]<< endl;
}
}
cout << endl;
//二维数组中的每个元素的地址
cout << "二维数组中的每个元素的地址" << endl;
for (i = 0; i < 2; i++)
{
cout << "第" << i << "个元素地址:" << a + i << endl;
}
cout << endl;
//下标访问二维数组
cout << "下标访问二维数组" << endl;
for (i = 0; i < 2; i++)
{
for (j = 0; j < 3; j++)
{
cout << "a[" << i << "]" << "[" << j << "]数据:" << a[i][j] << endl;
}
}
cout << endl;
//指针访问二维数组-1
cout << "指针访问二维数组-1" << endl;
for (i = 0; i < 2; i++)
{
//对 *(*(a+i)+j) 的解释:
//(a+i)指向的是存储一维数组地址(可理解为数组名)的地址
//*(a+i)是将对应的数组名取出来
//(*(a+i)+j)是一维数组每个元素的对应存储地址
//*(*(a+i)+j)将对应的一维数组的元素数据取出
for (j = 0; j < 3; j++)
{
cout << "a[" << i << "]" << "[" << j << "]数据:" << *(*(a+i)+j) << endl;
}
}
cout << endl;
//指针访问二维数组-2
cout << "指针访问二维数组-2" << endl;
for (p = a,i = 0; p < a+2; p++,i++)
{
for (j = 0; j < 3; j++)
{
cout << "a[" << i << "]" << "[" << j << "]数据:" << *(*p+j) << endl;
}
}
cout << endl;
}
TwodimensionalArray関数を実行するmain関数に入れると、結果は次のよう
になります。ポインターアクセス配列メソッド2では、定義されたポインターがint * pの場合、pはint型データに関連付けられているため、p = aを設定できません。そして、aが関連付けられているのは、長さが3の1次元整数配列です。したがって、ここでは、aに関連付けられた同じタイプのポインタ変数を定義します。aがpに割り当てられた後、pは変数であるため、p ++操作をpに対して実行できます。
要約:私はまだこの文が鋭敏であると思います:配列構造は再帰的であり、n次元配列の各要素はn-1次元配列です。
パラメータとしての配列
関数パラメーターとしての配列名
配列名を関数パラメータとして使用する場合、C ++はアドレス転送処理を行います。関数を呼び出すとき、形状パラメーターグループの名前は実パラメーターグループのアドレスを受け入れ、関数は仮パラメーターポインターを介して間接的に実パラメーターグループにアクセスします。
/**********************************************************
* 函数:PrintArray
* 描述:输出数组元素
* 参数:int x[] - 形参数数组名
int length - 数组长度
* 返回:无
* 备注:
**********************************************************/
void PrintArray(int x[], int length)
{
int i;
cout << "数组的元素为:" << endl;
for (i = 0; i < length; i++)
{
cout << x[i] << " ";
}
cout << endl;
}
int a[] = {
1,3,4,5,6,75,4,3};
int main()
{
PrintArray(a,sizeof(a)/ sizeof(int));
}
PrintArray関数のパラメーターintx []はパラメーター配列の名前であり、aはそのアドレスをパラメーターに渡し、配列aの要素はパラメーターを介して関数内でアクセスできます。
参考資料:C ++プログラミング基盤(Zhou Airu Lin Weijian)