如果声明问题

时间:2011-08-11 06:54:17

标签: c

看到我有一个复杂的代码,但我被困在一些地方,所以我只是给你一部分..

我有一个功能

function(int a,uint64_t b,int c);

当我调用函数

  uint64_t b;
  int c;

  printf("enter b");
  scanf("%d",&b);  // i m giving 1

   printf("enter c");
   scanf("%d",&c);  // i m giving 2

  function(0xcd32ab00 ,b ,c);

在该函数定义中,我将值b与另一个参数比较,如

 /*  magicNum is type uint64_t type & it has value 1 */
if(magicNum == b) 
{
 // do something
}

但是“做某事”不会发生; 当我打印magicNum& b都有值1,所以无法理解为什么会发生这种情况。

当我写

if((uint64_t)magicNum == (uint64_t)b) 
{
 // do something
}

这完美无缺。

我知道我犯了一个愚蠢的错误,但我没有得到......请帮助我...... 我正在使用32位Linux系统

2 个答案:

答案 0 :(得分:5)

您没有向我们展示您的原始代码有问题。那是因为以下工作正常:

#include <stdio.h>

static void fn (int a, uint64_t b, int c) {
    uint64_t magicNum = 1;
    if (magicNum == b)
        puts ("They match!");
    if ((uint64_t)magicNum == (uint64_t)b)
        puts ("They still match!");
}

int main (void) {

    fn (0xcd32ab00 ,1 ,2);
    return 0;
}

输出:

They match!
They still match!

根据您使用scanf("%d")获取值的更新,对于我们这些因使用了数十年C而被扭曲的人来说,这是一个众所周知的问题: - )

当您提供%d作为格式说明符时,它需要一个指向int类型的指针,它将写入该类型。如果您指定的指针是两倍宽的类型(比如64位而不是32位),它只会写入 half

你可以在这里看到:

int main (void) {
    uint64_t x = 0xffffffffffffffffULL;
    printf ("Enter your number: ");
    scanf ("%d", &x);     // signed int
    printf ("%llu\n", x); // unsigned long long
    return 0;
}

当你输入-4294967295时输出1(因为它没有触及变量的另一半,它仍然是1位)。

如果您将scanf格式字符串更改为使用%llu,则可以正常使用。

请注意,这只是因为我的unsigned long long值为64位宽,就像我的unit64_t值一样。为了便于携带,应该使用inttypes.h中的格式说明符宏。对于uint64_t,正确的是SCNu64。宏名称通过使用:

形成
  • PRI代表printf格式字符串,SCN代表scanf格式字符串。
  • diouxX指定带符号的十进制(d和{ {1}}),无符号八进制,无符号十进制,无符号小写十六进制和无符号大写十六进制。
  • 针对不同变量类型的可选iLEASTFASTMAX
  • PTR这是位大小。

N在我的实施中扩展为SCNu64,但并非所有情况都是如此。在具有64位"llu"和256位int的系统上,它很可能是long long(因为它等同于"u")。

显示如何使用这些格式字符串的示例代码如下所示:

unsigned int

至于为什么#include <stdio.h> #include <inttypes.h> int main (void) { uint64_t x = 0xffffffffffffffffULL; printf ("Enter your number: "); scanf ("%" SCNu64, &x); printf ("%" PRIu64 "\n", x); return 0; } 可以打印出减少的值,请参阅以下代码:

printf

输出:

#include <stdio.h>
#include <inttypes.h>

int main (void) {
    uint64_t x = 0xffffffffffffffffULL;
    printf ("Enter your number: ");
    scanf ("%u", &x);
    printf ("uint64_t = %" PRIu64 "\n", x);
    printf ("uint64_t = %" PRIu64 " (when and'ed)\n", x & 0xffffffffU);
    printf ("uint     = %u\n", x);
    return 0;
}

我怀疑你也用较小尺寸的格式字符串打印它。当你这样做时,它实际上是一个对齐问题。因为你的处理器是little-endian,所以它是偶然工作的(64位值的前32位是最低有效位,上例中为Enter your number: 5 uint64_t = 18446744069414584325 uint64_t = 5 (when and'ed) uint = 5 。)

但它会在你的printf中的之后填充中的任何参数,因为你已经将64位压入堆栈而5仅消耗32位,因此未对齐。

请参阅herehere以获取解释其工作原理的早期答案(或更准确地说,不起作用)。

答案 1 :(得分:2)

参数a和b交换??

 function(0xcd32ab00 ,1 ,2);

应该是

 function(1, 0xcd32ab00 ,2);