参数内部和外部的指针

pointers inside and outside parens

本文关键字:指针 外部 内部 参数      更新时间:2023-10-16
char errorString[20];
//See if it appears to be a 4-char-code
*(UInt32 *) (errorString + 1) = CFSwapInt32HostToBig(error);
if (isprint(errorString[1]) && isprint(errorString[2]) && isprint(errorString[3]) && isprint(errorString[4]))
{
    errorString[0] = errorString[5] = ''';
    errorString[6] = '';
}

函数的这一部分接受一个字符串(error)并检查它是否包含4个字符的代码。

发生了什么:*(UInt32 *) (errorString + 1)

为什么参数内部和外部都有一个指针,以及如何将值分配给errorString + 1

errorString可以被视为指针,因此,可以对其进行数学运算,例如,添加整数。 errorString + 1也是一个指针。它是指向errorString指向的位置旁边的位置的指针。

(UInt32 *)something something强制转换为指定类型的指针,因此(UInt32 *)(errorString + 1)现在是一个指向类型为 UInt32 的数据的指针。

*是一个取消引用运算符,因此将其应用于指针会得到指针指向的任何内容(例如,如果pointer指向整数,则*pointer将是整数)。

总而言之,此构造将尝试从指定位置提取类型 UInt32 的数据。

在表达式中

*(UInt32 *) (errorString + 1)

第一个*是取消引用,然后第二个*表示指针。 如果我们从右到左阅读它,我们有

(errorString + 1) // get a pointer to errorString + 1 of the type char*
(UInt32 *) // cast that pointer to a UInt32 *
* // dereference that pointer

括号内的星号是指针转换的一部分括号外的星号(如果表示尊重)

所以(UInt32 *) (errorString + 1)会发出错误字符串+1和UInt32指针*(UInt32 *) (errorString + 1)取消引用它,并将内容作为 UInt32 为您带来。

让我们从头开始。

表达式errorString的类型为char [20];除非它是sizeof或一元&运算符的操作数,否则其类型将从char [20]转换为char *,其值将是数组第一个元素的地址(&errorString[0])。

表达式 errorString + 1 产生数组第 2 个元素的地址(相当于 &errorString[1] ),其类型为 char *

(UInt32 *) (errorString + 1) 是一个强制转换表达式,它告诉编译器将errorString + 1的结果视为指向UInt32的指针,而不是指向char的指针。

*(UInt32 *) (errorString + 1)取消引用 (UInt32 *) (errorString + 1) 的结果,以便将 CFSwapInt32HostToBig() 的结果分配给从地址 errorString + 1 开始的 32 位对象

蹩脚的视觉辅助:

             +---+
errorString: |   | errorString[0]
             +---+                 
             |   | errorString[1]  <-------------+
             +---+                               |
             |   | errorString[2]                |
             +---+                               +-- Assign result of CFSwapInt32HostToBig()
             |   | errorString[3]                |   to these four bytes
             +---+                               |
             |   | errorString[4]  <-------------+
             +---+                 
             |   | errorString[5]
             +---+
              ...
             +---+
             |   | errorString[19]
             +---+