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;
}

変数を として取っているときはいつでもint正常に動作していますが、変数を として宣言している場合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]long *int *

次のコードを検討してください。

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(ただの代わりに書いている人をあまり見かけないので、 fromlongを削除するという通常の慣行を採用しました。有効かつ合法であり、 と同じことを意味するのは正しいです。ほとんどの人は余分な言葉、それだけです。)intlong intlong intlong

于 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

KnRANSICバージョンは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.

結論:intに長くキャストしないでください。データが失われ、バグが発生します。パラメータをlong型に変換してください。intとlongintが必要になる場合があります。

于 2013-03-10T04:48:23.690 に答える