我想将其第一个参数的“正确”大小作为第二个参数传递给函数mem
,这是一个无效的地址。
我想到使用宏MEM
,该宏使用运算符sizeof
。该宏应该在预处理时通过查看文本来“推断”“正确”的大小,即,第一个参数如何用代码编写。
除了我的宏,当参数是使用数组名称(arr
)传递的数组时,它不能很好地工作。 (请注意,如果我按照注释中的建议通过&arr
,则宏可以很好地工作)
#include <stdio.h>
#define MEM(addr) mem(addr,sizeof *addr) // <-- does not work for arrays
void mem(const void* , int );
int main()
{
int t=3;;
int arr[10];
int* p=&t;
MEM(&t); // --> mem(&t,sizeof *&t) <- OK!
MEM(p); // --> mem(p,sizeof *p <- OK!
MEM(arr); // --> mem(arr,sizeof *arr) <- NO! I WANT THE SIZE OF THE ALL ARRAY!
// SO I WANT --> mem(arr,sizeof arr)
return 0;
}
void mem(const void* pp, int bytestoread) // prints bytestoread bytes starting from address pp
{
int i;
unsigned char* p=(unsigned char*)pp;
for(i=0;i<bytestoread;i++)
{
if(i%8==0)
{
if(i!=0) printf("\n");
printf("%p: ",p);
}
printf("%02x ",*p);
p++;
}
printf("\n\n");
}
如果对我的问题有其他解决方案或方法,则可以使用宏,甚至更好。但是数组作为参数传递给函数时会衰减,因此我看不到如何使用函数来完成所需的操作。
即使对C预处理程序有一些改动,例如在代码中写入的地址名称上使用字符串化预处理程序运算符#
并相应地有选择地编译MEM,我也很高兴,但是我无法做到这一点。 (也许也使用#if #else #endif
预处理程序指令...?)
跟进:
以下将是一个试探性的解决方案,它利用了以下事实:对于数组arr
(与常规指针相反)&arr
==arr
...
#define SIZE(add) ( #add[0]=='&' ?
sizeof *add :
((void*)add==(void*)&add ? sizeof add : sizeof *add) )
#define MEM(address) mem( address, SIZE(address) )
......但是,当在代码中将address
写为&t
时(例如,t
是int
),这当然不会编译,因为&&t
不是在语法上正确,即使检查#add[0]=='&'
确保不会执行它。
1)是否有使其工作的方法?2)还是应该编写一个解析器,该解析器根据传递给解析器的文本输出要编译的代码?3)对于在#if指令中可以用作条件的条件,C预处理器为何如此严格? (我什至不能使用字符串文字或#运算符!只允许使用const表达式,例如2> 1或其他定义的宏)]
MEM
宏似乎没有明显的解决方案,尽管可能存在带有预处理器条件表达式的解决方案,其中根据操作数的类型,我们决定如何计算大小。
C中的常见做法是创建带有额外参数的函数,该参数占用数据容器的大小。因此,您将编写这样的内容,而根本不使用宏:
int t = 3;
int arr[10] = {0};
int *p = &t;
mem(&t, sizeof(t));
mem(p, sizeof(*p));
mem(arr, sizeof(arr) / sizeof(arr[0])); // <- 40/4 = 10
这非常冗长,但在这种情况下,您可以依靠此并确保获得预期的行为。