C语言有哪些鲜为人知的特性?及C语言未定义行为一览

译注:本文摘编自 Quora 的一个热门问答贴。 请在linux系统下测试本文中出现的代码Andrew Weimholt 的回复:switch语句中的case 关键词可以放在if-else或者是循环当中1234567891011121314
摘要由CSDN通过智能技术生成

译注:本文摘编自 Quora 的一个热门问答贴。 请在linux系统下测试本文中出现的代码

Andrew Weimholt 的回复:

switch语句中的case 关键词可以放在if-else或者是循环当中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
switch (a)
{
     case 1:;
       // ...
       if (b==2)
       {
         case 2:;
         // ...
       }
       else case 3:
       {
         // ...
         for (b=0;b<10;b++)
         {
           case 5:;
           // ...
         }
       }
       break ;
 
     case 4:

Brian Bi 的回复:

1. 声明紧随用途之后

理解声明有一条很简单的法则,不过不是什么“从左向右”这种没道理却到处宣传的法则。这一法则的观点是,一个声明是要告诉你,你所声明的对象要如何使用。例如:

1
2
3
4
int *p; /* *p是int类型的, 因此p是指向int类型的指针 */
int a[5]; /* a[0], ..., a[4] 是int类型的, 因此a是int类型的数组 */
int *ap[5]; /* *ap[0], .., *ap[4] 是int类型的, 因此ap是包含指向int类型指针的指针数组 */
int (*pa)[5]; /* (*pa)[0], ..., (*pa)[4] 是int类型的, 因此pa是指向一个int类型数组的指针 */

更多详情请看这里: Brian Bi’s answer to C (programming language): Why doesn’t C use better notation for pointers?

2. 指定初始化:

在C99之前,你只能按顺序初始化一个结构体。在C99中你可以这样做:

1
2
3
4
5
6
struct Foo {
     int x;
     int y;
     int z;
};
Foo foo = {.z = 3, .x = 5};

这段代码首先初始化了foo.z,然后初始化了foo.xfoo.y 没有被初始化,所以被置为0。
这一语法同样可以被用在数组中。以下三行代码是等价的:

1
2
3
int a[5] = {[1] = 2, [4] = 5};
int a[] = {[1] = 2, [4] = 5};
int a[5] = {0, 2, 0, 0, 5};
3. 受限指针(C99):

restrict关键词是一个限定词,可以被用在指针上。它向编译器保证,在这个指针的生命周期内,任何通过该指针访问的内存,都只能被这个指针改变。比如,在

1
2
3
4
5
6
int f( const int * restrict x, int * y) {
     (*y)++;
     int z = *x;
     (*y)--;
     return z;
}

编译器可能会假设,xy 所指的并不是同一个int对象,因为如果它们指向了同一个对象,则x的值将可以通过y修改,这正是你保证不会发生的。因此,将允许编译器来优化f,就好像函数原本被写做如下这样:

1
2
3
int f( const int * restrict x, int * y) {
     return *x;
}

如果你违反协议向f传递两个指向同一int对象的指针时,将产生未定义行为。

我猜想,引入这一特性最初的动机之一是想让C语言在数值计算时可以Fortran一样快。在Fortran 中,默认假定数组不会重叠,因此只有你通过restrict 限定词来显式的告诉编译器数组不能重叠,编译器才能在C语言中进行这样的优化。

4. 静态数组索引(C99)

<
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值