我想将其参数的正确大小(即地址)传递给函数mem
。
我想到使用宏MEM
,该宏使用运算符sizeof
。
除了当参数是数组时它不能很好地工作。因为它将其视为指针。
#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");
}
如果对我的问题有其他解决方案或方法,则可以使用宏,甚至更好。但是数组作为参数传递给函数时会衰减,因此我看不到如何使用函数来实现所需的功能。
另外,我必须指定指针类型,因此我认为我无法在函数中有效使用运算符sizeof。我错了吗?
即使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]=='&'
确保不会执行它。
有没有办法使它起作用?
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
这很冗长,但在这种情况下,您可以依靠此并确保获得预期的行为。