簡體   English   中英

在獲取長整型時的可疑指針轉換

[英]suspicious pointer conversion on taking long int

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

你能解釋一下原因嗎?

鑒於:

  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而不是long ,所以我采用了從long int刪除int的慣常做法。您是正確的,因為long int是有效和合法的,並且與long ;大多數人不寫多余的單詞,僅此而已。)

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.

結論:不要長時間轉換為int。 您將丟失導致bug的數據。將參數轉換為long類型。 它可以采用int,也可以采用long int。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM