指针初始化以遍历数组
Pointer Initialization to Iterate through Array
我有一个函数,其中有 2 个空指针(规范的一部分),但我知道它们是 char *
。我想遍历 char 数组,所以我尝试创建一些指针来遍历它们。当我执行以下操作时,我的程序无法运行:
int foo(void const * first, void const * second)
{
char const * firstIt = (const char*) first;
char const * secondIt = (const char*) second;
...
}
但是,如果我这样做:
int foo(void const * first, void const * second)
{
char const * firstIt = *(const char**) first;
char const * secondIt = *(const char**) second;
...
}
两者有什么区别,为什么第二个有效?我不知道我是否包含了足够的细节,所以如果需要更多信息,我很乐意提供。
如果第二个有效,那是因为你为函数指定的空指针实际上可以是任何东西,我猜你传递给函数的是指针的指针。例如,以下代码有效:
#include <stdio.h>
#include <stdlib.h>
int foo(void const * first, void const * second);
int goo(void const * first, void const * second);
int main () {
char * a, * b;
a = malloc (sizeof (char));
b = malloc (sizeof (char));
*a = 'z';
*b = 'x';
goo (&a, &b); /* critical line */
free (a);
free (b);
return 0;
}
int foo(void const * first, void const * second) {
char const * firstIt = (const char*) first;
char const * secondIt = (const char*) second;
printf ("%c %c", *firstIt, *secondIt);
return 1;
}
int goo(void const * first, void const * second) {
char const * firstIt = *(const char**) first;
char const * secondIt = *(const char**) second;
printf ("%c %c", *firstIt, *secondIt);
return 2;
}
但是,要使上述程序使用函数 foo
,您需要将关键行替换为以下形式的调用:
foo (a, b);
区别有意义吗?它是否解决了您的问题?
第一种方法假定调用者传递了一个 char *(以某种方式限定的 const)。
第二个假定调用者传递了一个 char **(以某种方式限定的 const)。
如果第二个有效,则意味着您的调用者正在传递一个字符 **。
第一个不起作用的原因是未定义的行为。拥有一种类型的指针,转换为另一种类型,并将其取消引用为除原始类型之外的任何其他类型会产生未定义的行为。通过 void 指针的往返不会改变这一点。
这就是为什么编译器抱怨从一种指针类型到另一种指针类型的隐式转换(进出 void 指针除外)。
我有一个函数,其中有 2 个空指针(规范的一部分),但我知道它们是 char *
。我想遍历 char 数组,所以我尝试创建一些指针来遍历它们。当我执行以下操作时,我的程序无法运行:
int foo(void const * first, void const * second)
{
char const * firstIt = (const char*) first;
char const * secondIt = (const char*) second;
...
}
但是,如果我这样做:
int foo(void const * first, void const * second)
{
char const * firstIt = *(const char**) first;
char const * secondIt = *(const char**) second;
...
}
两者有什么区别,为什么第二个有效?我不知道我是否包含了足够的细节,所以如果需要更多信息,我很乐意提供。
如果第二个有效,那是因为你为函数指定的空指针实际上可以是任何东西,我猜你传递给函数的是指针的指针。例如,以下代码有效:
#include <stdio.h>
#include <stdlib.h>
int foo(void const * first, void const * second);
int goo(void const * first, void const * second);
int main () {
char * a, * b;
a = malloc (sizeof (char));
b = malloc (sizeof (char));
*a = 'z';
*b = 'x';
goo (&a, &b); /* critical line */
free (a);
free (b);
return 0;
}
int foo(void const * first, void const * second) {
char const * firstIt = (const char*) first;
char const * secondIt = (const char*) second;
printf ("%c %c", *firstIt, *secondIt);
return 1;
}
int goo(void const * first, void const * second) {
char const * firstIt = *(const char**) first;
char const * secondIt = *(const char**) second;
printf ("%c %c", *firstIt, *secondIt);
return 2;
}
但是,要使上述程序使用函数 foo
,您需要将关键行替换为以下形式的调用:
foo (a, b);
区别有意义吗?它是否解决了您的问题?
第一种方法假定调用者传递了一个 char *(以某种方式限定的 const)。
第二个假定调用者传递了一个 char **(以某种方式限定的 const)。
如果第二个有效,则意味着您的调用者正在传递一个字符 **。
第一个不起作用的原因是未定义的行为。拥有一种类型的指针,转换为另一种类型,并将其取消引用为除原始类型之外的任何其他类型会产生未定义的行为。通过 void 指针的往返不会改变这一点。
这就是为什么编译器抱怨从一种指针类型到另一种指针类型的隐式转换(进出 void 指针除外)。