在C中处理数组的未知方式

时间:2015-10-08 12:41:09

标签: c

*--p = "0123456789abcdef"[num % 2];

您好,我正在阅读一些代码并看到了这一行。我目前正在学习C,我不明白为什么[num%2]的字符串面前。

如果您需要上下文,可以在此处阅读整个方法:

char * toBin(unsigned int num)
{
    static char retbuf[33];
    int i = 0;
    for (; i < 33; i++)
    {
        retbuf[i] = '0';
    }
    char *p;
    p = &retbuf[sizeof (retbuf) - 1];
    *p = '\0';
    do
    {
        *--p = "0123456789abcdef"[num % 2];
        num /= 2;
    }
    while (num != 0);
    return retbuf;
}

我知道方法在做什么:它将int数转换为二进制形式。我只是不明白第一个提到的行。我知道它是以某种方式将数组的(第二个)最后位置的位置于retbuf中,我也理解为什么它使用num%2来获得0和1。但我只是不明白为什么有一个字符串面前。

5 个答案:

答案 0 :(得分:8)

使用string相当于使用数组。在这种特定情况下,以下就足够了:

*--p = "01"[num % 2];

由于只使用了阵列的前2个位置。我假设整个字符串&#34; 01 ... ef&#34;来自转换为十六进制的类似函数。

答案 1 :(得分:4)

请记住,在C中,String只是一个字符数组。所以

*--p = "0123456789abcdef"[num % 2];

就像你有

一样
char digits[] = "0123456789abcdef";
....
*--p = digits[num % 2];

和alrady指出的其他人一样,*--p将设置为'0''1',具体取决于num是偶数还是奇数

答案 2 :(得分:3)

在C中,常量字符串指向其第一个元素的内存位置;

不带方括号的数组名也指向数组第一个元素的地址。因此,可以使用与使用数组相同的方式访问常量字符串中的元素。

参见下面的示例

char arr[10] = "Hello";

printf("%c %c", arr[4], "Hello"[4]);

它将打印字符'o'2次。 希望你能理解。

答案 3 :(得分:2)

为了记录,以防将来有人绊倒这个问题,发布的功能很糟糕,不能使用它。实现此算法的正确方法是这样的:

#include <inttypes.h>
#include <stdio.h>

char* uint32_to_binstr (uint32_t num, char buf[32+1]);

static size_t get_bin_digits (uint32_t i);

int main(void)
{
  char str[32+1];

  printf("%u\t-> %s\n",     0, uint32_to_binstr(    0, str));
  printf("%u\t-> %s\n",     2, uint32_to_binstr(    2, str));
  printf("%u\t-> %s\n",    15, uint32_to_binstr(   15, str));
  printf("%u\t-> %s\n",   255, uint32_to_binstr(  255, str));
  printf("%u\t-> %s\n", 12345, uint32_to_binstr(12345, str));
}

char* uint32_to_binstr (uint32_t num, char buf[32+1])
{
  const uint32_t BASE = 2;

  // count the number of binary digits in advance, to get a left-aligned string:
  size_t digits = get_bin_digits(num); 
  size_t i;

  for(i=0; i<digits; i++)
  {
    char ch = num % BASE + '0';
    buf[digits-i-1] = ch; // have to write string from right to left
    num /= BASE;
  }

  buf[i] = '\0';
  return buf;
}

static size_t get_bin_digits (uint32_t i)
{
  size_t digits = 0;

  if(i==0)
  {
    return 1;
  }

  for(; i>0; i>>=1)
  {
    digits++;
  }

  return digits;
}

输出:

0       -> 0
2       -> 10
15      -> 1111
255     -> 11111111
12345   -> 11000000111001

答案 4 :(得分:0)

我不知道为什么你在那里有六进制字符串,但它正在做的是将int num除以2,如果它甚至是n%2 = 0那么字符串的元素0将是选中(&#39; 0&#39;)如果它是奇数n%2 = 1,那么它将选择数组的元素1(&#39; 1&#39;)。在循环中,指针p在retbuff中向后移动以按顺序放置每个字符(&#39; 0&#39;或&#39; 1&#39;)

这是一种非常奇怪的方式