C中的连续指针转换

时间:2017-02-14 19:11:22

标签: c pointers

我正在查看一些示例代码,该代码使用API​​来了解如何正确使用API​​。我遇到了一些令我困惑的代码。以下是相关的代码块:

typedef struct myStruct_id{
randomStruct1 var1;
void *var2;
unsigned char *var3;
randomStruct2 var4;
int var5;
}myStruct_name;

//Function Prototype
void randomFunction(const randomStruct1 *in1, const randomStruct2 *in2, void *handle);

//Global Variables
//assuming data1-5 are of the correct types corresponding to randomStruct1, void, etc.
myStruct_name myStruct_var = {data1, data2, data3, data4, data5}; 
void *handle = (void*)myStruct_var; 

void main(){
    myStruct_name *local_var = (myStruct_name *)handle;
    //Other code here
    local_var.var2 = randomFunction(&local_var.var1, &local_var.var4, &(local_var));
}

我的理解是变量句柄是一个 null 泛型指针,指向变量myStruct_var(已经被类型转换为 null 泛型指针)。在main函数中,变量local_var是指向struct myStruct_name的指针,指向指针句柄的值(其类型转换为指向类型myStruct_name的指针),该指针指向变量myStruct_var。接下来,函数randomFunction将指针仅作为输入,指向var1的指针,指向变量local_var的指针。

我的困惑是:函数randomFunction需要指向结构的输入指针和 null 泛型指针。如果local_var已经是指针,为什么需要地址运算符(&)? local_var的值是不是已经是地址了?或者我对local_var发生的事情的理解不正确吗?

另外,有没有理由为randomFunction的最终输入是括号?也就是说,为什么它和&(local_var)而不仅仅是& local_var?括号是做什么的吗?

感谢阅读和任何回复!

编辑:感谢您的回复表明我没有引用空指针。我指的是 void "数据类型"这里是通用的。

1 个答案:

答案 0 :(得分:2)

如果你的背景是Java或其他一些" safe"语言,指针真的很难包裹起来。但在核心,你只是在处理记忆。

第一个问题 - 为什么指针的地址?

以下是您可以使用的示例代码。它试图实现一个"浅"以两种方式交换。

#include <stdio.h>

typedef struct {int x; int y; int z;} XYZ;

XYZ s1 = {1, 2, 3};
XYZ s2 = {4, 5, 6};

void swap1(XYZ *a, XYZ *b);
void swap2(XYZ **a, XYZ **b);

int main()
{
    XYZ *p = &s1;
    XYZ *q = &s2;

    printf("Before\n");
    printf("Contents s1: %d %d %d s2: %d %d %d\n", s1.x, s1.y, s1.z, s2.x, s2.y, s2.z);
    printf("Contents p: %d %d %d q: %d %d %d\n", p->x, p->y, p->z, q->x, q->y, q->z);
    printf("Addresses: %p %p %p %p %p %p\n", &s1, &s2, p, q, &p, &q);

    swap1(p, q);

    printf("Swap 1\n");
    printf("Contents s1: %d %d %d s2: %d %d %d\n", s1.x, s1.y, s1.z, s2.x, s2.y, s2.z);
    printf("Contents p: %d %d %d q: %d %d %d\n", p->x, p->y, p->z, q->x, q->y, q->z);
    printf("Addresses: %p %p %p %p %p %p\n", &s1, &s2, p, q, &p, &q);

    swap2(&p, &q);

    printf("Swap 2\n");
    printf("Contents s1: %d %d %d s2: %d %d %d\n", s1.x, s1.y, s1.z, s2.x, s2.y, s2.z);
    printf("Contents p: %d %d %d q: %d %d %d\n", p->x, p->y, p->z, q->x, q->y, q->z);
    printf("Addresses: %p %p %p %p %p %p\n", &s1, &s2, p, q, &p, &q);

    return 0;
}

void swap1(XYZ *a, XYZ *b)
{
    XYZ *t;
    t = a;
    a = b;
    b = t;
}

void swap2(XYZ **a, XYZ **b)
{
    XYZ *t;
    t = *a;
    *a = *b;
    *b = t;
}

当你编译并运行上面的代码时,你会得到这样的东西:

Before                                                                                                                 
Contents s1: 1 2 3 s2: 4 5 6                                                                                           
Contents p: 1 2 3 q: 4 5 6                                                                                             
Addresses: 0x60103c 0x601048 0x60103c 0x601048 0x7ffd29c58288 0x7ffd29c58280                                           
Swap 1                                                                                                                 
Contents s1: 1 2 3 s2: 4 5 6                                                                                           
Contents p: 1 2 3 q: 4 5 6                                                                                             
Addresses: 0x60103c 0x601048 0x60103c 0x601048 0x7ffd29c58288 0x7ffd29c58280                                           
Swap 2                                                                                                                 
Contents s1: 1 2 3 s2: 4 5 6                                                                                           
Contents p: 4 5 6 q: 1 2 3                                                                                             
Addresses: 0x60103c 0x601048 0x601048 0x60103c 0x7ffd29c58288 0x7ffd29c58280 

请注意,交换1没有做任何事情,只是在交换2处,指针的地址被使用,交换发生了。另请注意,s1s2保持不变。您可以使用此函数来实现不需要复制整个结构的排序。

第二个问题:为什么&(local_var)&local_var

差异在功能上并不重要。它可能是前一个表达的残余,cut&amp; amp;粘贴,任何东西。很多原因。