首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用宏参数声明变量

如何使用宏参数声明变量
EN

Stack Overflow用户
提问于 2019-03-21 21:46:49
回答 1查看 1.1K关注 0票数 2

我得到了一些宏的描述,我必须定义它们。

DECL_LIST(类型,名称)

扩展到可调整大小数组实现中使用的三个变量的声明语法,即name_len、name_cap和name (指针本身)。

CHECK_CAP( type,name )扩展到代码中,以确保可调整大小的数组有足够的容量容纳另一个元素,如果没有,则可以放大。

·SIZE( name )

展开为当前存储在数组中的元素数的表达式。

·FOR( var,极限)

扩展到for循环的第一行,该循环使用一个名为var的int变量从0迭代到(但不包括)限制。

·交换(类型,a,b )

展开为一个代码块,该代码块交换给定类型的两个变量a和b的值。我们需要类型参数来声明一个临时变量,以帮助交换值。

逻辑是因为这个排序函数已经存在。我只需要在被操纵函数的宏中使用相同的逻辑:

代码语言:javascript
运行
复制
// Put your macro definitions here.  That should be all
// you need to do to complete this exercise.
#define DECL_LIST(type, name) \
    int name ## _cap = 5;     \
    int name ## _len = 0;     \
    type *name = (type *) malloc(name ## _cap * sizeof(type)); 

#define CHECK_CAP(type, name)                                         \
if ( name ## _len >= name ## _cap ) {                                 \
name ## _cap *= 2;                                                    \
name = (type *) realloc(name, name ## _cap * sizeof(type)); \
}  

#define SIZE(name)    \
sizeof(name)/sizeof(name[0]) 


#define FOR(var, limit) { \
  int var = 0;  \
for( int i = 0; i < limit; i++) {          \
       var++;           \
}    \
}

#define SWAP(type, a, b)   \
type temp = a; \
   a = b; \
   b = temp; 


int main()
{
  // Make a resizable list.
  DECL_LIST( double, list );

  double val;
  while ( scanf( "%lf", &val ) == 1 ) {
    // Grow the list when needed.
    CHECK_CAP( double, list );

    // Add this item to the list
    list[ SIZE( list ) ] = val;
    SIZE( list ) += 1;
  }

  // Bubble-sort the list.
  FOR( i, SIZE( list ) )
    FOR( j, SIZE( list ) - i - 1 )
      if ( list[ j ] > list[ j + 1 ] )
        SWAP( double, list[ j ], list[ j + 1 ] );

  // Print out the resulting, sorted list, one value per line.
  FOR( i, SIZE( list ) )
    printf( "%.2f\n", list[ i ] );

  return EXIT_SUCCESS;
}

这是在转换之前的主要功能:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
int main()
{
// Make a resizable list.
int list_cap = 5;
int list_len = 0;
double *list = (double *) malloc( list_cap * sizeof( double ) );
double val;
while ( scanf( "%lf", &val ) == 1 ) {
// Grow the list when needed.
if ( list_len >= list_cap ) {
list_cap *= 2;
list = (double *) realloc( list, list_cap * sizeof( double ) );
}
// Add this item to the list
list[ list_len ] =val;
list_len++;
}
// Bubble-sort the list.
for ( int i = 0; i < list_len; i++ )
for ( int j = 0; j < list_len - i - 1; j++ )
if ( list[ j ] > list[ j + 1 ] ) {
double tmp = list[ j ];
list[ j ] = list[ j + 1 ];
list[ j + 1 ] = tmp;
}
// Print out the resulting, sorted list, one value per line.
for ( int i = 0; i < list_len; i++ )
printf( "%.2f\n", list[ i ] );
return EXIT_SUCCESS;
}

这是在进行一些建议更改后的编译器输出:

代码语言:javascript
运行
复制
error: lvalue required as left operand of assignment
     SIZE( list ) += 1;
                  ^
sortList.c:50:8: warning: unused variable ‘i’ [-Wunused-variable]
   FOR( i, SIZE( list ) )
        ^
sortList.c:22:7: note: in definition of macro ‘FOR’
   int var = 0;  \
       ^
sortList.c:52:18: error: ‘j’ undeclared (first use in this function)
       if ( list[ j ] > list[ j + 1 ] )
                  ^
sortList.c:52:18: note: each undeclared identifier is reported only once for each function it appears in
sortList.c:53:15: error: expected expression before ‘double’
         SWAP( double, list[ j ], list[ j + 1 ] );
               ^
sortList.c:29:1: note: in definition of macro ‘SWAP’
 type temp = a; \
 ^
sortList.c:31:8: error: ‘temp’ undeclared (first use in this function)
    b = temp; 
        ^
sortList.c:53:9: note: in expansion of macro ‘SWAP’
         SWAP( double, list[ j ], list[ j + 1 ] );
         ^
sortList.c:56:8: warning: unused variable ‘i’ [-Wunused-variable]
   FOR( i, SIZE( list ) )
        ^
sortList.c:22:7: note: in definition of macro ‘FOR’
   int var = 0;  \
       ^
sortList.c:57:29: error: ‘i’ undeclared (first use in this function)
     printf( "%.2f\n", list[ i ] );

如果我当前的宏是正确的,有什么建议吗?我对描述有点困惑。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-21 22:13:17

您的老师希望您使用预处理器标记粘贴来创建一个替换代码的宏。例如,第一个宏如下所示

代码语言:javascript
运行
复制
#define DECL_LIST(type, name) \
    int name ## _cap = 5; \
    int name ## _len = 0; \
    type *name = (type *) malloc(name ## _cap * sizeof(type));

并将替换此代码

代码语言:javascript
运行
复制
// Make a resizable list.
int list_cap = 5;
int list_len = 0;
double *list = (double *) malloc( list_cap * sizeof( double ) );

关于CHECK_CAP宏的问题,您的老师希望您用宏替换这段代码。

代码语言:javascript
运行
复制
// Grow the list when needed.
if ( list_len >= list_cap ) {
    list_cap *= 2;
    list = (double *) realloc( list, list_cap * sizeof( double ) );
}

但是保持这段代码完整

代码语言:javascript
运行
复制
// Add this item to the list
list[ list_len ] =val;
list_len++;

稍后,您可以将list_len替换为SIZE宏。

希望这将帮助您理解为什么宏不需要修改list_len

FOR应该是

代码语言:javascript
运行
复制
#define FOR(var, limit) \
    for (int var = 0; var < limit; var++)

您需要在SWAP周围使用大括号,因为它扩展到多行:

代码语言:javascript
运行
复制
  if ( list[ j ] > list[ j + 1 ] ) {
     SWAP( double, list[ j ], list[ j + 1 ] );
  }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55289744

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档