C陷阱和缺陷

1. a+++++b 的含义是什么?

#include <stdio.h>

int main(int argc,char** argv)
{
    int a = 1;
    int b = 2;
    int c = 0;
    c = a++ + ++b;
    printf("C's value is%d\n",c);
    return 0;
}

#如果 c=a++a+++b; 会报lvalue required as increment operand

2.模拟计算机启动硬件将调用首地址为0位置的子例程

(*(void(*)())0)()

理解上面的代码:

1.括号优先级最高

2.假设fp变量是一个函数指针,如果调用fp所指向的函数 ->(*fp)()  ANSIC C 标准允许简写成fp()  但是我们得记住这是一个简写  因为编译器会自动判断需要的是一个指针,如果不是会报错。(对新手不友好)

3.(*0)()  我们理解为地址为0的函数指针 但是为0的地址不存在所以要做类型转换

4.将常数0转型为“指向返回值为void的函数指针”  (void(*)())0

5.用fp替换(void (*)())0  *((void (*)())0)()

6.用typedef 更清晰的表达 typedef void(*funcptr)(); (*(funcptr)0)();

 

3.运算符的优先级的问题

  运算符很多,不好记

  *p++  同 *(p++)  而不是 (*p)++   *p()同*(p())而不是(*p)()  a.b.c 同 (a.b).c 

  所以我们记住两点:

  1.任何一个逻辑运算符的优先级低于任何一个关系运算符

  2.移位运算符的优先级要比算术运算符的优先级低,但是比关系运算符要高

4.数组与指针的问题

  1.C语言中只有一维数组(C99允许变长数组),数组中的元素可以是任何类型,也可以是数组

  2.对于一个数组 ,我们只能够做两件事情:确定数组的大小和获取指向该数组下标为0的元素的指针。其他的操作看似是通过数组下标进行的,实际上是通过指针进行的。

  *(a+i) 即数组a中下标为i元素的引用,常用所以简写为a[i]

 5.非数组指针

实现字符串的链接

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

int main(int argc ,char** argv)
{
    char *s = "I love";
    char *t = "china";
    char *r; //*malloc( ) 可以确保有内存空间可以开辟  现在可以忽略
    r = malloc(strlen(s)+strlen(t)+1); //+1 是'/0' 字符串结束位
    if(!r) { //or NULL == r
        printf("开辟内存空间失败");
        return -1;
    }
    strcpy(r,s);
    strcat(r,t);
    printf("string r is:%s\n",r);
    return 0;
}

 

posted @ 2019-06-24 15:46  wpgraceii  阅读(254)  评论(0编辑  收藏  举报