在C中混淆指针和数组

时间:2013-08-08 20:01:29

标签: c arrays pointers

我试图理解以下代码中的错误。代码应该在两个数组之间切换。

我看到它只切换前4个字节。以下是否正确?

  1. 传递&num1num1是相同的(都传递数组中第一个元素的地址)。
  2. (char**)投射错误。那是因为当你传递和数组时,你传递了它所放置的地址。所以你实际上传给了void*
  3. 如何通过指针实际切换这两个数组?那可能吗?

    我知道从一开始我就定义了char **num1char **num2。但我希望它能保留数组符号!

    #include <stdio.h>
    void fastSwap (char **i, char **d)
    {
        char *t = *d;
        *d = *i;
        *i = t;
    }
    int main ()
    {
        char num1[] = "hello";
        char num2[] = "class";
        fastSwap ((char**)&num1,(char**)&num2);
        printf ("%s\n",num1);
        printf ("%s\n",num2);
        return 0;
    }
    

2 个答案:

答案 0 :(得分:4)

  

传递&amp; num1或num1是相同的(两者都传递数组中第一个元素的地址)。我是对的吗?

没有。第一个是指向数组本身(类型为char (*)[6])的指针,而在第二种情况下,指针指向第一个元素(指向type char *;数组在传递给函数时衰减为指向其第一个元素的指针。

  

(char *)投射错误

的确,您正在向char (*)[6]投射char **

  

所以你实际上在这里传递了一个空虚(我是否正确?)。

没有。不合逻辑的推论。我不知道void类型在这里是如何相关的。你有指针,数组,并最终指向数组。


数组不是指针。您的代码正在尝试交换数组,这是没有意义的,因为不允许分配给数组。您可能想要的是

予。或者获取指向每个字符串的第一个字符的指针,然后交换指针本身,如下所示:

void swap_pointers(const char **a, const char **b)
{
    const char *tmp = *b;
    *b = *a;
    *a = tmp;
}

const char *p1 = "hello";
const char *p2 = "world";
swap_pointers(&p1, &p2);

II。或者使用实际数组,然后交换内容:

void swap_contents(char *a, char *b, size_t n)
{
    for (size_t i = 0; i < n; i++) {
        char tmp = a[i];
        a[i] = b[i];
        b[i] = tmp;
    }
}

char a1[] = "hello";
char a2[] = "world";
swap_contents(a1, a2, strlen(a1));

另外,您可能需要阅读this

答案 1 :(得分:-1)

1. Passing &num1 or num1 is the same (both pass the address of the first element in the array)

不正确,&num1为您指向指向整个字符串“hello”(char * [6])的指针,而num1只是指向字符块的指针“你好“(char [6])。

2. The (char*) casting is wrong. That's because When you pass and array you pass the address it's laid in. So you actualy pass here a void (Am i correct?).

它仍然不是一个空白,它只是一个指向字符指针的指针。如果它是无效的,那么做void** myVoid = &num1之类的事情是完全有效的。这将导致语法错误,除非您在分配之前明确地将char **强制转换为void **。

问题是您的显式类型转换&num1char**这是不正确的,它是char*[6]。但是,当然,您不能将变量声明为char*[6],因此不能以这种方式使用它。要解决此问题,您需要将num1num2声明为:

char* num1 = "hello";
char* num2 = "class";

而是保持其他一切相同。事实上,通过此更改,您无需将&num1标记为char**,因为它已经是那样。