# C语言考古报告: 从K&R C到C99的函数声明

03 Jun 2016 (+0800)

## K&R C

double square();        /* 声明 */
...
...
...
double square(x)        /* 定义 */
double x;
{
return x * x;
}

#include <stdio.h>

double square();

main()
{
square(1, 2, 3, 4, 5);
return 0;
}

double square(x)
double x;
{
return x * x;
}

## C89/C99

double square(double);

int icmp(int *a,int *b)
{
return *a - *b;
}

#include <stdlib.h>
#include <stdio.h>

int icmp(int *a, int *b) { return *a - *b; }

int main(void)
{
int i ,a[] = {3 ,7 ,4 ,1 ,0 ,9 ,6};
qsort(a ,sizeof a / sizeof *a, sizeof *a, icmp);
for (i = 0; i < sizeof a / sizeof *a; ++i)
printf("%d\n", a[i]);
return 0;
}

qsort(
a,
sizeof a / sizeof *a,
sizeof *a,
(int (*)(const void *, const void *))icmp
);

int icmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}

qsort(a, sizeof a / sizeof *a, sizeof *a, (int (*)())icmp);

#include <stdlib.h>
#include <stdio.h>

int icmp();

int main(void)
{
int i, a[] = {3, 7, 4, 1, 0, 9, 6};
qsort(a, sizeof a / sizeof *a, sizeof *a, icmp);
for (i = 0; i < sizeof a / sizeof *a; ++i)
printf("%d\n", a[i]);
return 0;
}

int icmp(int *a, int *b)
{
return *a - *b;
}

## 默认参数提升

#include <stdio.h>

double square();

main()
{
printf("%f\n", square(1));
return 0;
}

double square(x)
double x;
{
return x * x;
}

printf("%f\n", square(1.0));

printf("%f\n", square(1.0f));

1. 如果传入的参数是是比int更小的整数类型, 那么它会被尝试转化为int类型; 如果其值超出了int的表示范围, 则将其转化为unsigned类型;
2. 如果传入的参数是float类型，则它会被转化为double类型入栈.

float square(); /* 声明 */
...
...
...
float square(float x)   /* 定义 */
{
return x * x;
}

float square(double x)
{
float y = (float)x;
return y * y;
}

square(1.0f);
square(1.0);

float square(float);    /* 声明 */
...
...
...
float square(float x)   /* 定义 */
{
return x * x;
}

int printf(char *fmt, ...);