我正在学习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)();
答案 0 :(得分:4)
char *(*ptr)[4]
是指向char
(char*
)的长度为4的指针数组的指针。由于arr
是4
char*
的长度ptr
数组,因此可以通过为arr
分配arr
的地址来&arr
, void *(*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。