10

我偶然发现了一个 C 代码,其中变量似乎是在函数的参数列表之后声明的。我不知道这是可能的。

在代码中,int r并在 .int *a的参数列表之后声明arr2int。这对局部变量arof有何影响arr2int

我想理解代码的真正原因是,如果我让它在我的 linux x86a[1] = 1上运行,那是我第一次调用的时候//MARKERarr2int

但是如果我让它在基于 ARM 的 omap4 开发板上运行a[1]=0,我不知道为什么会有差异。

有人可以对此发表评论吗?

long arr2int(a,r)
int r;
int *a;
{
   int i;
   long mul, result = 0, temp;

   //MARKER
   for (i=1; i<=r; i++) {
      mul = 1;
      temp = a[i]-1;
      while (temp--)
         mul = mul << 1;
      result += mul;
   }
   return(result);
}

以及调用方法:

void generateEncodingTable(){
    register int i,j;
    long temp;
    int seed = 133757;

    printf("\n[I] - Generating Encoding Table\n");
    for (pattern = 0; pattern < 4096; pattern++) {
        temp = pattern << 11;          /* multiply information by X^{11} */
        encoding_table[pattern] = temp + get_syndrome(temp);/* add redundancy */
    }

    decoding_table[0] = 0;
    decoding_table[1] = 1;
    temp = 1; 
    for (i=2; i<= 23; i++) {
        temp *= 2;
        decoding_table[get_syndrome(temp)] = temp;
    }

    a[1] = 1; a[2] = 2;

    temp = arr2int(a,2);
    decoding_table[get_syndrome(temp)] = temp;
    for (i=1; i<253; i++) {
        nextcomb(23,2,a);
        temp = arr2int(a,2);
    decoding_table[get_syndrome(temp)] = temp;
    }

    a[1] = 1; a[2] = 2; a[3] = 3;
    temp = arr2int(a,3);
    decoding_table[get_syndrome(temp)] = temp;
    for (i=1; i<1771; i++) {
        nextcomb(23,3,a);
        temp = arr2int(a,3);
        decoding_table[get_syndrome(temp)] = temp;
    }
}
4

5 回答 5

6

这是一种称为 K & R(Kernighan & Ritchie,以 Brian Kernighan 和 Dennis Ritchie 命名)的旧符号,用于声明函数。如果您的编译器支持它,您可以使用它,它与使用 ANSI 表示法声明函数相同。

于 2013-08-01T12:46:22.103 回答
5

正如其他人所提到的,这是一种早期的函数编码风格。

以下是这种风格的一个陷阱。 请注意,对传递的参数没有类型检查。可以解释您的运行时间差异。

假设你声明了一个函数

int foo(a,b,c);

编译器此时看到的只是一个名为“foo”的函数,它接受 3 个参数并返回一个int. 因此使用检查仅限于此。

让我们假设sizeof(short)< sizeof(int)<sizeof(long)并且函数定义为

int foo(a,b,c)
  int a;
  long b;
  int c;
{ /* code body */ }

注意以下用法foo

int d,e,f;
d = foo(1,2L,3);
e = foo((short)1,2L,3);
f = foo(1,2,3);

第一种用法工作正常,正确大小的整数被传递给foo.
第二种用法也很好用。第一个参数在调用之前被提升为int大小,就像在传递到之前printf("%d", (short)2)提升(short)2到。 第三个是一个问题,因为编译器不知道第二个参数需要是. 因此传递给的数据没有正确传递。--> UBintprintf()
longfoo

于 2013-08-01T14:05:23.357 回答
2

这是一个旧的 C 语法。如果您的编译器可以吞下它,那么它应该像您以正常的 ANSI 方式声明函数一样工作。

于 2013-08-01T12:40:49.703 回答
2

这就是K&R C,即Brian Kernighan 和Dennis Ritchie的The C Programming Language第一版所描述的C 语言。第二版已转向 ANSI C(C89)。

你应该总是使用 ANSI C 风格:

国际标准的基本原理 - 编程语言 C 6.11.6 函数声明符

将使用“旧式”函数声明和定义(即不使用原型的传统式)定性为过时,这表明委员会的意图是新的原型式最终应取代旧式。

这个案例的要点是新语法解决了 K&R 中定义的语言的一些最明显的弱点,新风格在每一个方面都优于旧风格。

于 2013-08-01T12:42:27.170 回答
0

它只是声明函数参数类型的一种方式:

void func (first_param, second_param)
int first_param;
int second_param;
{
 // ...
}

等于

void func (int first_param, int second_param)
{
 // ...
}
于 2019-03-12T09:15:49.787 回答