0
int main()
{
    long int i,t,n,q[500],d[500],s[500],res[500]={0},j,h;
    scanf("%ld",&t);
    while(t--)
    {
        scanf("%ld %ld",&n,&h);
        for(i=0;i<n;i++)
            scanf("%ld %ld",&d[i],&s[i]);
        for(i=0;i<h;i++)
            scanf("%ld",&q[i]);
        for(i=0;i<h;i++)
        {
            for(j=0;j<n;j++)
            {
                res[j]=d[j]+q[i]*s[j];
            }
        j=cal(res,n,q[i],s);
        printf("%ld\n",j);
        }
    }
    return 0;
}

long int cal(int res[],int n,int q,int s[])
{
    long int i,max=0,p,pos=0;
    for(i=0;i<n;i++)
    {
        if (max==res[i])
        {
            pos=add(res,s,pos,i,q);
            max=res[pos];
        }
        if (res[i]>max)
        {
                max=res[i];
                pos=i;
        }
    }
    return pos;
}

每当我使用变量 as 时int,它都可以正常工作,但是如果我将变量声明为 as long int,我会在函数调用中收到警告消息“可疑指针转换”——在以下行中:

(j=cal(res,n,q[i],s));

你能解释一下原因吗?

4

2 回答 2

4

鉴于:

  1. long int i,t,n,q[500],d[500],s[500],res[500]={0},j,h;
  2. j=cal(res,n,q[i],s);
  3. long int cal(int res[],int n,int q,int s[])

您正在尝试将数组传递long res[500]给需要int. 即使sizeof(int) == sizeof(long)在你的机器上,类型是不同的——而且我的机器上的尺寸肯定是不同的。

如果您在 Windows(32 位或 64 位)或 32 位 Unix 上,您将侥幸逃脱,但如果您迁移到 LP64 64 位环境,一切都会崩溃。

这就是为什么它是一个“可疑的指针转换”。这不是犹太洁食;它不可靠;它恰好适用于您的环境(但出于可移植性原因,它非常可疑)。


但是为什么它会给出“可疑指针转换”的警告(而不是“需要 L 值”的预期消息)?

我不确定你为什么会期待一个l-value required错误。请记住,当您调用函数时,数组会衰减为指针,因此您的函数声明也可以编写long cal(int *res, int n, int q, int *s),并且您传递long res[500]的内容会自动更改为long *(就像您编写的一样&res[0]),因此您传递的是 a long *where an int *is预期的,你可能会侥幸逃脱(因此是“可疑的”而不是更严重的)。

考虑代码:

long res[500];
long cal(int res[]);

int main(void)
{
    return cal(res);
}

64 位机器(和 64 位编译)上的 GCC 4.7.1 说:

x.c: In function ‘main’:
x.c:6:5: warning: passing argument 1 of ‘cal’ from incompatible pointer type [enabled by default]
x.c:2:6: note: expected ‘int *’ but argument is of type ‘long int *’

(我不经常看到人们写作long int而不仅仅是long,所以我采用了删除intfrom的惯常做法long int。你说得对,这long int是有效且合法的,并且与 的意思相同long;大多数人不写多余的话,仅此而已。)

于 2013-03-10T04:34:02.510 回答
0

ISO C 9899 在 6.3.1.1 中表示算术操作数

The rank of long long int shall be greater than the rank of long int, which
shall be greater than the rank of int, which shall be greater than the rank of short
int, which shall be greater than the rank of signed char

KnR ANSI C 版本在 2.2 中表示数据类型和大小

short is often 16 bits long, and int either 16 or 32 bits. Each compiler is free to     choose appropriate sizes for its own
hardware, subject only to the the restriction that shorts and ints are at least 16     bits, longs are
at least 32 bits, and short is no longer than int, which is no longer than long.

结论:不要将 long 转换为 int。您将丢失导致错误的数据。将您的参数转换为长类型。它可以采用 int 和 long int。

于 2013-03-10T04:48:23.690 回答