c语言|关于C编程语言,几乎没有人知道的事


c语言|关于C编程语言,几乎没有人知道的事
首先话不多说 , 直接给您去介绍咯 。
在C语言中 , 您可以在类型转换中 , 运算符内部 , 函数声明中声明新类型 。 sizeof
int a = sizeof(enum E { A B C ) + (enum X { D E F ) 0;
enum E e = B;
int b = e + F;

在C循环中 , “头”和循环体是两个单独的(嵌套的)作用域
for (int i = 0; i < 10; ++i)
{
int i = 42; // <-C语言中的OK , 声明其他局部变量


这不同于C ++ , 后者两者都形成一个范围 。
可以在C中进行[递归
调用main
在C语言中 , 可以在声明中显式地重复cv限定词
const const const const int i = 42;

在C中 , 您可以在相同的翻译单元中一次又一次地定义相同的文件作用域对象 , 只要这些定义仍然是暂定的即可(不要多次包含初始化器)
int i;
int i;
int i i i i;

与流行的看法相反 , C不支持不同指针类型之间以及整数和指针类型之间的隐式转换
int *p = 0;
double *pd = p; //<-在C中不允许
char *pc = 123;// <-在C中不允许

但是支持隐式的指针往返转换void * 。
将运算符应用于可变修改后的类型时 , 将sizeof在运行时对其进行评估
int i = 0;
sizeof(int [++ i
); //运行时`sizeof`将使`i`递增

int a [20
;
sizeof(a [++ i
); //编译时`sizeof`不会使`i`递增

typedef用C -declaration实际上可以生成可执行代码 , 如果声明为可变类型(一个VLA) 。 因此 , 绕过该声明进入该声明的范围是非法的typedef
goto skip;

int n = 42;
typedef int A[n
;

skip:;

即使main应该声明为返回int , 也不需要显式地return从中进行任何操作int main() 。 如果控制从末尾流出main , 则其行为就像return 0;
运算符sizeof有两种独立的语法:一种用于类型 , 另一种用于表达式 。 后者没有()围绕其论点
int a;
sizeof a; // 不需要在`a`附近使用`()`

从C99语句(如if , 等)开始for , while创建自己的隐式块 。 在C99块之前 , 仅由的显式对创建{ 。
标准C从未允许人们在声明中完全省略decl-specifier-seq 。 即使在具有“隐式int”规则的C89 / 90中 , 也无法将函数声明为foo() 。 你可以做extern foo()或者const foo() , 例如 , 而不是foo() 。
带空的函数声明()是K&R样式的声明 。 不建议使用K&R样式的声明 。 如果您的函数没有参数 , 则将其声明为(void) , 而不是() 。
函数声明和函数原型不是一回事 。 在现代C语言中 , 需要使用函数声明 。 但是功能原型不是 。
即使在函数参数列表中 , 诸如int *array和的声明int array[
通常是“等效的” , 后一种形式仍要求数组元素类型完整 , 而前一种则不需要
struct Incomplete;
void foo(struct Incomplete *array);
void bar(struct Incomplete array[
);

在函数参数列表中声明指针时 , 可以将指针本身声明为 const
void foo(int *const array);

在C89 / 90中 , 使用参数声明的“等效”数组形式时 , 以前不可能声明相同类型的常数 。 但是 , 由于C99 , 可以通过const在[

void bar(int array[const
); // 与?int * const array`相同

使用函数参数声明的数组形式时 , 数组的大小通常无关紧要
void foo(int array[5
); //等同于`int array [
` 。 `5`被忽略 。


推荐阅读