c - 如何使用宏参数声明变量
问题描述
我得到了一些宏的描述,我必须定义它们。
DECL_LIST(类型,名称)
扩展为可调整大小数组实现中使用的三个变量的声明语法,name_len、name_cap 和 name(指针本身)。
CHECK_CAP( type, name ) 扩展到代码以确保可调整大小的数组有足够的容量容纳另一个元素,如果没有,则扩大它。
• 尺寸(姓名)
展开为当前存储在数组中的元素数量的表达式。
• FOR(var, limit)
展开到 for 循环的第一行,该循环使用名为 var 的 int 变量从 0 迭代到(但不包括)limit。
• 交换(类型、a、b)
扩展为交换给定类型的两个变量 a 和 b 的值的代码块。我们需要类型参数来声明一个有助于交换值的临时变量。
这个排序功能的逻辑已经存在。我只需要在被操纵函数的宏中使用相同的逻辑:
// 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;
}
这是转换之前的原始 main 函数:
#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;
}
这是进行一些建议更改后的编译器输出:
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 ] );
如果我当前的宏是正确的,有什么建议吗?我对描述有点困惑。
解决方案
您的老师希望您使用C 预处理器标记粘贴来创建替换代码的宏。例如,第一个宏看起来像这样
#define DECL_LIST(type, name) \
int name ## _cap = 5; \
int name ## _len = 0; \
type *name = (type *) malloc(name ## _cap * sizeof(type));
并将替换此代码
// Make a resizable list.
int list_cap = 5;
int list_len = 0;
double *list = (double *) malloc( list_cap * sizeof( double ) );
关于你关于CHECK_CAP
宏的问题,你的老师希望你用宏替换这段代码
// 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++;
稍后,您可以list_len
用您的SIZE
宏替换。
希望这将帮助您理解为什么宏不需要修改list_len
.
FOR
应该
#define FOR(var, limit) \
for (int var = 0; var < limit; var++)
您需要使用大括号,SWAP
因为它会扩展到多行:
if ( list[ j ] > list[ j + 1 ] ) {
SWAP( double, list[ j ], list[ j + 1 ] );
}
推荐阅读
- javascript - 如何在 .js 文件中使用 .ts 文件中的变量
- arrays - 尝试在 Flutter Streambuilder 中构建一个喜欢/不喜欢按钮 - 不工作
- nginx - 在 Synology nginx 反向代理后面不允许 Zammad 社区零星错误 405
- c# - CS0120 非静态字段需要对象引用
- javascript - 在特定时间后重定向到另一个页面并显示倒计时
- python - 通过查询内联替换 AST 节点
- c# - 消费者传奇何时/如何完成?
- ionic-framework - 为什么 jhipster-ionic 会失败?
- c# - 如何在 C# 中的图像上添加带有文本的边框?
- android - E/dalvikvm: JNI ERROR (app bug): local reference table overflow (max=512)