如何在C中使用宏将循环计数器变量转换为char?

时间:2017-02-23 07:44:06

标签: c arrays macros

我的程序中有一些char数组。这些数组的数量是固定的,每个数组的名称由一个' S'字符和数字如下:

char *s0="aaasa";
char *s1="bssbaabb";
char *s2="bbbssbaaaa";
.
.
char *sX="bcccbaabaab";
int num_arrays=X;

我决定使用宏来打印数组的内容但是没有成功(我是宏的新手)。 所以我不知道如何使用宏来在for循环中打印数组的内容,如下所示:

#X(s,i) //what should be here?

for(int i=0;i<X;i++){
   printf("s%d: %s \n",i, X(s,i) );
}

感谢。

3 个答案:

答案 0 :(得分:2)

答案你做不到

简单地说,因为宏是编译的,不能用你的for循环。

使用指向字符串的指针数组,例如:

char* pointers[] = {
    "String1",
    "String2",
    "...."
};

printf的用法(在for循环中使用sizeof来标识要打印的数组中的元素数量):

for (int i = 0; i < sizeof(pointers) / sizeof(pointers[0]); i++) {
    printf("s%d: %s \n", i, pointers[i]);
}

答案 1 :(得分:1)

假设你的所有字符串都是常量,你可以在没有宏的情况下执行以下操作(它们往往是一个坏主意恕我直言):

const char *S[] = {
   "string1",
   "string2",
   "strin3",
   NULL
};


for(int i=0; s[i];i++){
   printf("s%d: %s \n",i, s[i] );
}

https://ideone.com/fNUMJ4

PS:使用NULL作为列表末尾的标记 - 可以使用sizeof s/sizeof (s[0])代替

答案 2 :(得分:1)

听起来像你正在钓鱼的是所谓的&#34; X宏&#34;。请注意,应尽可能避免这些,因为它们使代码非常难以阅读。

这里最正确的解决方案是简单地使用数组。如果您发现自己需要其他东西,根本原因可能是糟糕的程序设计。其他发布的答案显示了普通数组的正确解决方对于非常特殊的情况,X宏应该是最后的手段。

话虽这么说,这就是你用X宏实现这个目标的方法:

#include<stdio.h>

#define STRING_LIST \
X(0, "aaasa")       \
X(1, "bssbaabb")    \
X(2, "bbbssbaaaa")  \
X(3, "bcccbaabaab")

int main(void)
{
  // declare pointers s0 to s3:
  #define X(i, str) const char* s##i = str;
    STRING_LIST
  #undef X

  // print data by using pointers s0 to s3:
  #define X(i, str) printf("s%d: %s \n", i, s##i);
    STRING_LIST;
  #undef X

}

如果你想将它与一个循环/数组结合起来,那么如果我们进行完全C延迟&#34;并做这样的事......

// Definitely NOT recommended practice but can be studied for learning purposes
#include<stdio.h>

#define STRING_LIST \
X(0, "aaasa")       \
X(1, "bssbaabb")    \
X(2, "bbbssbaaaa")  \
X(3, "bcccbaabaab")

// determine the size of the X macro list by using an enum:
typedef enum
{
  #define X(i, str) DUMMY_##i,
    STRING_LIST
  #undef X
  STRINGS_N
} strlist_size_t;


// declare union with both pointers s0 to s3 and an array:
typedef union
{
  struct // C11 anonymous struct
  {
    #define X(i, str) const char* s##i;
      STRING_LIST
    #undef X
  };

  const char* array [STRINGS_N];
} strlist_t;


int main(void)
{
  // ensure that the type punning is safe on the given system:
  _Static_assert(sizeof(strlist_t) == sizeof(const char* [STRINGS_N]), 
                 "Struct padding detected! Type punning failed.");

  // initialize list:
  strlist_t strlist = 
  {
    #define X(i, str) .s##i = (str),
      STRING_LIST
    #undef X
  };

  // print data by using pointers s0 to s3:
  #define X(i, str) printf("s%d: %s \n", i, strlist.s##i);
    STRING_LIST;
  #undef X

  printf("\n");

  // print data using a loop:
  for(int i=0; i<STRINGS_N; i++)
  {
    printf("s%d: %s \n", i, strlist.array[i]);
  }
}