据我了解,如果将 int 变量中的单个位作为指针传递,则似乎可以寻址它。我说的对吗?
uint8_t adcState[8];
uint16_t adcMessageId[8];
void adcEnable(uint8_t* data) {
// Set ADC Input as enabled
adcState[(uint8_t) data[0]] = 1;
// Get ADC Message ID
adcMessageId[(uint8_t) data[0]] = data[2] << 8 | data[1];
}
到目前为止,这就是我发现的:
该函数接收指向 8bit int 的指针作为参数
它获取该 int 的最低有效数字(指针被视为数组,并且正在读取其第一个字段),并将其用作
adcState
数组的字段编号,然后将其设置为1
。例如,这意味着如果数据被729
,data[0]
将被'9'
,因此adcsState[9]
变得1
。 可能吗?你能像这样使用指针吗?对于
adcMessageId
数组,采用了类似的方法。但是,此处分配的值取决于数据 int 的第三位和第二位数字。我不明白这里的转变。作为一个
uint8_t
值,它只有 8 位,因此用 8 位移动总是给出 0000 0000。因此,带有data[1]
的OR本身就是data[1]
... 在我们的例子中,adcMessageId[9]
将变为('7' << 8
)按位或与'2'
,所以只需'2'
。
我的逻辑似乎有些不对劲。
似乎data
指向一个数组,而不是单个 8 位int
,并且:
的第一个元素是指向数组的指针
adcState
和adcMessageId
数组的第二个和第三个元素包含数组的数据值
adcMessageId
正如评论者@Eugene Sh.所指出的那样,
data[2]
在转移之前被提升为int
,因此不会丢失任何位。
指针表示法uint8_t *
与函数签名中的数组表示法uint8_t []
传递数组一样有效;这通常是传递字符串char *
方式,并且数组在传递给函数时会衰减到指向其第一个元素的指针。
- 该函数接收指向 8bit int 的指针作为参数
是的,粗略地说。 函数实现假设指向的uint8_t
可以被视为至少三个uint8_t
数组的第一个元素。
- 它获取该 int 的最低有效数字(指针被视为数组,并且正在读取其第一个字段),并使用它 作为
adcState
数组的字段编号,然后设置为1
。为 例如,这意味着如果data
是729
,则data[0]
将为"9"并且 因此,adcsState[9]
变为"1"。可能吗?你能用吗 像这样的指针?
不,你完全误解了。data[0]
的意思与*data
完全相同。 它是指data
指向的 8 位无符号整数。 数字729太大,不能表示为uint8_t
,但是如果data
指向的对象的值为129,那么data[0]
的计算结果是129。
您可能对后面的外观感到困惑data[1]
和data[2]
的功能. 这些是指内存中*data
后面的两个uint8_t
对象,例如,如果data
指向数组的第一个元素,它们将可靠地存在,正如我上面提到的。 使用[]
编制索引不会产生切片data
指向的uint8_t
的效果。
还要注意,我说的是"data
指向的对象"。 不会直接传递uint8_t
值作为此函数的参数。 预计整数值不会被重新解释为指针。 将指针传递给希望函数处理的数据。
- 对于
adcMessageId
数组,采用了类似的方法。但是,此处分配的值取决于data
国际。
在adcMessageId
情况下,data[0]
再次指data
指向的uint8_t
。data[1]
指的是记忆中另一个完整的uint8_t
,data[2]
到下一个。
我不明白这里的转变。作为一个uint8_t值,它只有 8 位,因此用 8 位移动总是给出 0000 0000。
uint8_t
只有 8 位,但所有小于int
的整数值都会转换为至少与int
一样宽的整数类型,或者可能转换为浮点类型,以进行算术运算。 特定的升级类型部分取决于其他操作数是什么,并且结果具有相同的升级类型。 在所有符合 C 的实现中,类型int
至少为 16 位宽。 因此,这...
data[2] << 8 | data[1]
......打算将两个uint8_t
值打包到一个 16 位整数中,data[2]
和data[1]
,data[2]
位于最重要的位置。 这并不完全安全,因为data
的元素将被提升为(signed
)int
而不是unsigned int
,但这只会在int
宽度为16位的实现上带来问题(这在当今并不常见),即使这样,也只有在data[2]
的值大于127时才会出现问题。 一种更安全的表达方式是显式强制转换:
(unsigned int) data[2] << 8 | (unsigned int) data[1]
你有一些误解。或者也许只是措辞错误。
该函数接收指向 8bit int 的指针作为参数
更准确地说,它获取指向 8 位整数数组的指针。否则,您的使用将无效。可能它得到一个指向字符串的指针。
它采用该 int 的最低有效数字(指针被视为数组,并且正在读取其第一个字段),
这是错误的。您似乎将其用作指向包含数字的字符串的指针。 在这种情况下,您可以访问第一个字符,这是最有效的十进制数字。
并将其用作 adcState 数组的字段编号,然后将其设置为 1。例如,这意味着如果数据为 729,则数据 [0] 将为"9",因此 adcsState[9] 变为"1"。可能吗?你能像这样使用指针吗?
你把事情搞砸了一点。 如果您想访问十进制数字,我们谈论的是字符串,第一个元素是'7'
不要与7
混淆。
对于 adcMessageId 数组,采用了类似的方法。但是,此处分配的值取决于数据 int 的第三位和第二位数字。
如果你使用字符串,也许你不应该谈论 int。
我不明白这里的转变。作为一个uint8_t值,它只有 8 位,因此用 8 位移动总是给出 0000 0000。因此,带有数据[1]的OR本身就是数据[1]...在我们的示例中,adcMessageId[9] 将变为 ('7' <<8) 按位 OR 与 '2',所以只是 '2'。
这已经在评论和Govind Parmar的回答中得到解决:整数提升在转移之前发生。