获取运算符sizeof来区分简单地址,指针广告数组(可能带有宏?)

问题描述 投票:0回答:1

我想将其参数的正确大小(即地址)传递给函数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时(例如,tint),这当然不会编译,因为&&t不是在语法上正确,即使检查#add[0]=='&'确保不会执行它。

有没有办法使它起作用?

c pointers macros sizeof preprocessor
1个回答
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

这很冗长,但在这种情况下,您可以依靠此并确保获得预期的行为。

© www.soinside.com 2019 - 2024. All rights reserved.