双指针和它们之间的括号

时间:2015-03-20 07:38:51

标签: c++ c pointers

我正在学习c指针,我按照c4learn作为教程。在pointer to array of string部分,其中包含以下代码:

char *arr[4] = {"C","C++","Java","VBA"};
char *(*ptr)[4] = &arr;

我没有得到什么

*(*ptr)[4]

?没有可能像

一样使用它
**ptr

代替?

UPDATE1:

目前我在下一部分function pointer,我又看到了类似的代码:

void *(*ptr)();

4 个答案:

答案 0 :(得分:4)

char *(*ptr)[4]

是指向charchar*)的长度为4的指针数组的指针。由于arr4 char*的长度ptr数组,因此可以通过为arr分配arr的地址来&arrvoid *(*ptr)();

void*

指向无参数函数的指针返回void* fun(); // function void *(*ptr)(); // function pointer p = fun; // function pointer points to function 。例如

T

C语法可能会令人困惑,因此使用一些示例可能更容易说明这一点。请注意,;T name[N]; // size N array of T T * name[N]; // size N array of pointer to T T (*name)[N]; // pointer to size N array of T T ** name[N]; // size N array of pointer to pointer to T T *(*name)[N]; // pointer to size N array of pointer to T 之间的空格没有区别。

{{1}}

答案 1 :(得分:0)

char *ar[4];

将ar声明为四个指向chars的指针数组。

要声明指针,您可以声明它可以指向的内容,并将变量名替换为(*some_other_name)

所以char *(*ptr)[4];将ptr声明为指向chars的四个指针数组的指针。通常你可以删除括号,但在这种情况下,char **ptr[4];会将ptr声明为指向字符指针的四个指针的数组,这不是我们想要的。

类似于函数指针。 void *fn()声明一个函数。 void *(*ptr)()声明一个可以指向fn的指针。 void **ptr()将声明一个具有不同返回类型的函数。

答案 2 :(得分:0)

  

是不是可以像**ptr那样使用它?

是的,假设您的意思是下面的ptr2

const char* arr[4] = {"C","C++","Java","VBA"};
const char* (*ptr)[4] = &arr;
const char** ptr2 = arr;

但有一个区别是...... ptr类型仍然会对数组长度进行编码,因此您可以将ptr而不是ptr2传递给下面的函数:

template <size_t N>
void f(const char* (&arr)[N]) { ...can use N in implementation... }
  

目前我在下一部分,函数指针,我再次看到类似的代码:void *(*ptr)();

创建一个指向函数的指针 - 不带参数 - 返回void*(即未指定类型的数据的地址,或nullptr)。

答案 3 :(得分:0)

char *(*ptr)[4]指向指针数组的数组指针

语法模糊不清:如果你有一个普通数组int arr[4];,那么你可以通过声明int (*arr_ptr)[4]数组指针添加到这样的数组中。

所以有数组,常规指针和数组指针。事情变得令人困惑,因为当您单独使用数组名称arr时,它会衰减为指向第一个元素的常规指针。类似地,如果你有一个常规指针并让它指向数组,ptr = arr;它实际上只指向数组的第一个元素。

另一方面,数组指针指向“整个数组”。如果您从上面的示例中获取sizeof(*arr_ptr),则在32位计算机上将获得4*sizeof(int),4 * 4 = 16个字节。

应该注意的是,数组指针是一个温和有用的东西。如果你是初学者,你真的不需要浪费时间去理解这是什么。数组指针主要是出于语言一致性的原因。数组指针唯一真正实用的是数组数组上的指针算法和dynamic allocation of multi-dimensional arrays