#include<stdio.h>
#define SIZE 3
int main()
{
char intArrayOne[SIZE] = {'A', 'B', 'C'};
char (*ptrToAnOneDimArray)[SIZE] = &intArrayOne;
int i = 0;
for(i=0 ; i<SIZE ; i++)
{
printf("%c ", (*ptrToAnOneDimArray)[i]);
}
}
Output
A B C
我们何时应该使用“ptrToAnOneDimArray” - C / C ++中的各种用法?请给我一个真实的例子。
我们可以避免这些复杂而模糊的指针用法吗?
答案 0 :(得分:3)
例如,当您想要实现动态多维数组时:
int (*ptrArr)[WIDTH] = malloc(sizeof ptrArr[0] * HEIGHT);
比
更好int **ptrPtr = malloc(sizeof ptrPtr[0] * HEIGHT);
for (size_t i = 0; i < HEIGHT; i++) {
ptrPtr[i] = malloc(sizeof ptrPtr[0][i] * WIDTH);
}
出于各种原因(确实指向内存中连续的2D数组,它需要更少的分配和释放,因此您不太可能获得它错了,等等。)
答案 1 :(得分:0)
假设您是嵌入式程序员。现在你有一些带有可交换模块的硬件。对于每个模块,您必须以不同方式进行通你以不同的方式初始化/读/写它。
现在您的软件必须处理所有这些模块类型。你有3个例程(在这里简化)来初始化,读取,写入每个类型模块(HW0是模块A,HW1是模块B)。
void HW0_init() { printf("HW0_init\n"); }
void HW0_read() { printf("HW0_read\n"); }
void HW0_write(){ printf("HW0_write\n"); }
void HW1_init() { printf("HW1_init\n"); }
void HW1_read() { printf("HW1_read\n"); }
void HW1_write(){ printf("HW1_write\n"); }
现在想象你想要启动你的模块并从中读取它,所以你可以:
int hw_id = 1;
// want to init hardware
switch(hw_id)
{
case 0: HW0_init(); break;
case 1: HW1_init(); break;
// ...
}
// now I want to read
switch(hw_id)
{
case 0: HW0_read(); break;
case 1: HW1_read(); break;
// ...
}
使用指向数组的指针可以有所不同。如果您声明指向函数的指针数组,如下所示:
// as many arrays as you have modules
void (*hw0[3])() = { HW0_init, HW0_read, HW0_write };
void (*hw1[3])() = { HW1_init, HW1_read, HW1_write };
您的代码可能会简化为:
enum HW_ACTION
{
HW_INIT = 0,
HW_READ = 1,
HW_WRITE = 2
};
// pointer to array of pointers to funcs taking nothing
// and returning nothing
void (*(*f)[3])(void);
// detect hardware and set 'f'
f = &hw1;
(*f)[HW_INIT](); // same as HW1_init(); <=> hw1[HW_INIT]();
(*f)[HW_READ](); // same as HW1_read(); <=> hw1[HW_READ]();
相同的效果 - '更简单的代码'。
对于没有C ++编译器的C用户,您可以将其视为poor's man virtual methods
,您通常会使用init
,read
,write
方法创建基本抽象类并实现它们对于各种模块。
答案 2 :(得分:-1)
指针指针(因此通过代理指向数组指针)非常有用。如果你有一个函数/方法并且它需要一个指向值的参数,你可以改变函数内部的值,并且当你离开函数时该值仍然在范围内 - 当然是通过引用传递。但是,您无法更改指针指向的地址 - 例如使您传递给NULL指针的指针,或将其指向内存中其他位置的不同值。如果你使用指针到指针的值,那么你可以改变&#39;中间值的值。你的函数内的指针。我认为MySQL C-connector库是一个使用它的例子。
在您的例如,你可以通过ptrToAnOneDimArray
成一个函数,使* ptrToAnOneDimArray是空指针或指向某些其他数据而不是intArrayOne
- 为intArrayOne
的大小是固定通过编译器(在堆栈上),然后您可以动态地将堆栈中的* ptrToAnOneDimArray更新为堆上的数组malloc()&#39; d。
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
void display(char* data) {
int i = 0;
for(i=0 ; i<SIZE ; i++) {
printf("%c ", data[i]);
}
}
void changeMyArgument(char** pointerToPointer) {
*pointerToPointer = (char*) malloc(SIZE * sizeof(char));
/* now we use array notation for a change */
(*pointerToPointer)[0] = 'X';
(*pointerToPointer)[1] = 'Y';
(*pointerToPointer)[2] = 'Z';
}
int main() {
/* intArrayOne is implicitly char* */
char intArrayOne[SIZE] = {'A', 'B', 'C'};
char* arraysArePointers = intArrayOne;
/* ptrToAnOneDimArray is implicitly char** */
char** ptrToAnOneDimArray;
ptrToAnOneDimArray = &arraysArePointers;
display(*ptrToAnOneDimArray);
changeMyArgument(ptrToAnOneDimArray);
display(*ptrToAnOneDimArray);
}