繁体   English   中英

C中的指针的整数运算

[英]integer arithmetic on pointers in C

下面的语句将计算数组的长度吗?

UART1_BUF[1] = (unsigned char)(lcl_ptr - (unsigned char *)&UART1_BUF[1]);

////////////////////////////////////////////////// ///////////////////////////////////

unsigned char UART1_BUF[128];

void apple_Build_SetFIDTokenValues(void)
/* apple_Build_SetFIDTokenValues - 
 * 
 * This function builds the apple protocol StartIDPS() command.
 */
{
 unsigned char * lcl_ptr;
 UART1_BUF[0] = BT_START_OF_PACKET;
 UART1_BUF[1] = 0x00;

 //BundleSeedIDPrefToken    
 lcl_ptr = apple_Build_BundleSeedIDPrefToken(&UART1_BUF[1]);

 UART1_BUF[1] = (unsigned char)(lcl_ptr - (unsigned char *)&UART1_BUF[1]);
*lcl_ptr = apple_checksum((unsigned char *)UART1_BUF, UART1_BUF[1]);
 UART1_BUF[UART1_BUF[1]] = *lcl_ptr;
}

unsigned char * apple_Build_BundleSeedIDPrefToken(unsigned char *buf_ptr)
{
    *(buf_ptr++) = 0x0D; //length of BundleSeedIDPrefToken minus this byte
    *(buf_ptr++) = BundleSeedIDPref_Token_FID_TYPE;
    *(buf_ptr++) = BundleSeedIDPref_Token_FID_SUBTYPE;
    //BundleSeedIDString
    *(buf_ptr++) = '0';
    *(buf_ptr++) = '0';
    *(buf_ptr++) = '0';
    *(buf_ptr++) = '0';
    *(buf_ptr++) = '0';
    *(buf_ptr++) = '0';
    *(buf_ptr++) = '0';
    *(buf_ptr++) = '0';
    *(buf_ptr++) = '0';
    *(buf_ptr++) = '0';
    *(buf_ptr++) = '0';
    return (buf_ptr);
}

是的,只要结果适合一个字节(从代码示例中可以得出),并且用“数组长度”表示字节数减去包头。

它会为您提供apple_Build_BundleSeedIDPrefToken()函数添加的字节数。 (已填充到UART_BUF[]数组中的字节总数比该数多一,因为该语句将不计入UART_BUF[0]处的字节。)

一般情况下,减去类型的两个指针T *成型的元件的阵列T给你的差作为元素的数量(而不是字节数)。 (如果两个指针中的任何一个都不指向同一数组中的一个元素,或者不指向最后一个数组之后的元素,则结果是不确定的。)结果本身具有带符号的整数类型ptrdiff_t ,该类型在<stddef.h>定义<stddef.h>

但是,这里两个指针都指向相同的unsigned char数组,因此每个元素根据定义都是一个字节。

因此,表达式lcl_ptr - (unsigned char *)&UART1_BUF[1]将给出函数添加的字节数。 (请注意, &UART_BUF[1]已经是unsigned char *类型的,因此无需在表达式内进行&UART_BUF[1] 。)

然后将该表达式转换为unsigned char ,尽管理论上上面的示例显然没有,但理论上可以截断结果。


我注意到代码有点奇怪,因为它分配了UART_BUF[1] 3次!

  1. UART1_BUF[1] = 0x00; 将其设置为0;
  2. lcl_ptr = apple_Build_BundleSeedIDPrefToken(&UART1_BUF[1]); 在调用的函数中将其设置为0x0D
  3. UART1_BUF[1] = (unsigned char)(lcl_ptr - (unsigned char *)&UART1_BUF[1]); 将其设置为0x0E ,因为该函数增加了14个字节。

更一般地说,记住要小心指针减法:期望它们总是给出一定数量的字节是一个常见的错误...

#include <stdio.h>
#include <stddef.h>

int main(void)
{
    int array[4];
    int *start, *end;

    start = &array[1];
    end = &array[3];
    printf("Difference (as int *): %d\n", end - start);
    printf("Difference (as char *): %d\n", (char *)end - (char *)start);
    return 0;
}

给定(在sizeof(int)==4 ):

Difference (as int *): 2
Difference (as char *): 8

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM