简体   繁体   English

用 memcmp() 比较整数

[英]Comparing integers with memcmp()

I am making a function to get the maximum value of an array of NMEMB members each one of size SIZ, comparing each member with memcmp() .我正在制作一个 function 来获取每个大小为 SIZ 的 NMEMB 成员数组的最大值,并将每个成员与memcmp()进行比较。 The problem is that when comparing signed integers the result is incorrect but at the same time correct.问题是在比较有符号整数时,结果是不正确的,但同时是正确的。 Here is an example:这是一个例子:

void *
getmax(const void *data, size_t nmemb, size_t siz){

    const uint8_t *bytes = (const uint8_t *)data;
    void *max = malloc(siz);

    if (!max){
        errno = ENOMEM;
        return NULL;
    }
    
    memcpy(max, bytes, siz);
    while (nmemb > 0){

        hexdump(bytes, siz);

        if (memcmp(max, bytes, siz) < 0)
            memcpy(max, bytes, siz);

        bytes += siz;
        --nmemb;
    }

    return max;
}

int
main(int argc, char **argv){
    int v[] = {5, 1, 3, 1, 34, 198, -12, -11, -0x111118};
    size_t nmemb = sizeof(v)/sizeof(v[0]);
    int *maximum = getmax(v, nmemb, sizeof(v[0]));
    printf("%d\n", *maximum);
    return 0;
}
  • hexdump() is just a debugging function, doesn't alter the program. hexdump()只是一个调试 function,不会改变程序。

When compiling and executing the output is the following:编译执行output时如下:

05 00 00 00 // hexdump() output
01 00 00 00
03 00 00 00
01 00 00 00
22 00 00 00
c6 00 00 00
f4 ff ff ff
f5 ff ff ff
e8 ee ee ff
-11  // "maximum" value

Which is correct since memcmp() compares an string of bytes and doesn't care about types or sign so -11 = 0xfffffff5 is the maximum string of bytes in the array v[] but at the same time is incorrect since -11 is not the maximum integer in the array.这是正确的,因为memcmp()比较一个字节串并且不关心类型或符号,所以-11 = 0xfffffff5是数组v[]中的最大字节串,但同时不正确,因为-11不是数组中的最大 integer。

Is there any way of getting the maximum integer of an array using this function?有没有办法使用这个 function 获得数组的最大 integer?

Go down the qsort route and require a custom comparator. Go 沿着qsort路线并需要自定义比较器。 Note that you absolutely don't need dynamic memory allocation in a function this simple:请注意,您绝对不需要在 function 中进行动态 memory 分配,这很简单:

#include <stdio.h>

void const *getmax(void const *data, size_t const count, size_t const elm_sz,
                   int (*cmp)(void const *, void const *)) {
  char const *begin = data;
  char const *end = begin + count * elm_sz;
  char const *max = begin;
  while (begin != end) {
    if (cmp(max, begin) < 0) max = begin;
    begin += elm_sz;
  }

  return max;
}

int int_cmp(void const *e1, void const *e2) {
  int const i1 = *(int const *)e1;
  int const i2 = *(int const *)e2;

  if (i1 > i2) return 1;
  if (i1 < i2) return -1;
  return 0;
}

int main() {
  int v[] = {5, 1, 3, 1, 34, 198, -12, -11, -0x111118};
  int const *maximum = getmax(v, sizeof(v) / sizeof(*v), sizeof(*v), int_cmp);
  printf("%d\n", *maximum);
}

memcmp compares the locations and does not care about the sign. memcmp比较位置并且不关心符号。 so for it -11 means 0xFFFFFFF5 and -12 means 0xFFFFFFF4 and means 0xFFFE4DF4 and the biggest number in the array 198 means 0x000000C6 , so out of all these, -11 is the biggest unsigned number and it is returned for you.所以对于它-11表示0xFFFFFFF5-12表示0xFFFFFFF40xFFFE4DF4并且数组198中的最大数字表示0x000000C6 ,所以在所有这些中, -11是最大的无符号数,它会为您返回。 You should not use memcmp to compare the signed numbers.您不应该使用memcmp来比较带符号的数字。

All memory comparisons made by memcmp are unsigned and based on char sized array elements. memcmp进行的所有 memory 比较都是无符号的,并且基于char大小的数组元素。 When you feed this with a signed int array of cells, different size, your result can only be used to test equality of binary representations, meaning that a result of 0 or different than 0 means equality or unequality, but the sign on a different of zero result means comparing the individual bytes of the array of integeres, which, descomposed as bytes (in the machine endianness architecture), makes some of the bytes to be signed and compared as unsigned and others be signed and compared as unsigned.当您使用不同大小的有signed int单元格数组来提供它时,您的结果只能用于测试二进制表示的相等性,这意味着0或不同于0的结果表示相等或不等,但不同的符号零结果意味着比较整数数组的各个字节,这些字节被分解为字节(在机器字节序架构中),使一些字节被签名并作为无符号进行比较,而其他字节被签名并作为无符号进行比较。 In addition, the significance of the different bytes in an integer will probably affect the sorting order, as the bytes are compared from lower addresses to higher addresses, that would match with the architecture endianness only in the case that the integers where stored as unsigned and (very important) stored in memory in big endian order .此外,integer 中不同字节的重要性可能会影响排序顺序,因为字节是从低地址到高地址进行比较的,只有在整数存储为unsigned和(非常重要)以大端顺序存储在 memory 中 If probably you are using intel architecture, then this is just the opposite to be able to use that.如果您可能正在使用英特尔架构,那么这与能够使用它正好相反。

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

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