《C和指针》读书笔记 中篇

目录

 

结构和联合

动态内存分配

使用结构和指针

高级指针话题

预处理器

说实在的,书看过了很容易忘记,还是要经常复习复习,最主要的是要知道有那么个东西,忘记了不要紧,要用的时候知道有这么个东西就知道去哪找


结构和联合

  1. 聚合数据类型:同时存储超过一个的单独数据。C提供了两种类型的聚合数据类型,数组和结构。
  2. 结构声明
    1. 深色的三个部分至少要出现两个。
    2.       
    3. 采用标签       
    4. 更好的方式Simple由结构标签变成了类型名
  3. 结构成员可以是标量,数组,指针,和甚至是其他结构。
  4. 结构体通过名字通过点运算符 . 调用结构成员。这是直接访问,用指向结构变量的指针是间接访问 -> 
  5. 结构体的自引用:如果结构体包含一个类型为该结构自身的成员,这是非法的,因为这样会无限重复下去。而如果结构体包含一个类型为该结构自身的成员的指针,则是合法的,如链表,树等都是通过这样实现的。    
  6. 不完整声明:如果每个结构都引用了其他的结构,那么哪个结构应该首先声明。
  7. 结构对象的指针px指向的是结构第一个成员的位置,但是被声明为一个指向结构的指针,所以表达式*px的结果是整个结构,而不是它的第一个成员。
  8. 结构对象进行传参时如果不使用指针,传参效率会很低,因为c语言都是按值传递,结构体如果拷贝过去效率就会低下很多。要先传递到堆栈,然后丢弃掉。
  9. 联合:联合中的所有成员使用的是内存中的相同的位置。利用好了可以变得高效
  10. 联合的初始化
  11. 特殊的结构体:位段例子
  12. 警告的总结

动态内存分配

  1. 首先为什么要内存分配:在面对未知的情况时尽可能的减少内存的浪费,也可以避免特定情况下数组的溢出。
  2. 维护一个可用内存池的函数 malloc 和 free
    1. mallco分配的内存是连续的
    2. 如果内存池为空,malloc向操作系统请求内存,如果操作系统无法返回内存,malloc返回一个NULL指针,因此对每个从malloc返回的指针进行检查,确保它非NULL很重要
    3. 对于边界对齐的机器,malloc分配的内存将满足边界对齐最严格的要求。
    4. free参数要么是NULL,要么是之前从malloc calloc realloc返回的值。
  3. 另外两个内存分配函数
    1. calloc不同于malloc在于返回的内存先全部设为0然后返回指针,而且参数为元素数量和元素的字节数。然后计算总的
    2. realloc 修改已经分配的内存的大小。原有内容保留,从尾部增加或删除,增加的内存未初始化。如果第一个参数为NULL那么它和malloc效果就一样了。
  4. 一个例子:
    1. 可移植
    2. 使用下标初始化
    3. 间接初始化
  5. 动态内存使用的一些错误
  6. 一个不易出错的内存分配器
  7. free的易犯错误
  8. 警惕内存泄漏

使用结构和指针

  1. 链表节点创造新节点并插入到已有的链表中
  2. 写一个将节点插入到一个从小到大排序的链表的函数要考虑的两点
    1. 访问链表节点的成员前一定要先检查它是不是一个NULL,否则容易出错。
    2. 如果要插入的节点在链表中值最小,换句话说在链表头插入一个新节点。解决方法是用一个空的节点的指针放在首位。Node **linkp 是指向链表头结点的指针的指针。
  3. 双链表:反正要记住链表前面一定要有一个空的节点的指针作为插入到首节点的操作做准备。比如这个,rootp就是头节点,且是空的节点,且向前的指针指向最后一个结点。

高级指针话题

  1. 高级声明
    1. 看个例子    int      *a;    它把*a声明为一个整数,由此推断出a是一个指向整数的指针。所以 int   *f,g;只有f是指针,g是整型。
    2. int   *f();   f是一个返回指向int类型指针的函数,而 int   (*f)();  第二个括号是函数操作调用符,第一对括号只起到了聚组的作用,它迫使间接访问在函数调用之前进行,使f成为了一个函数指针,它所指向的函数用于返回一个整数值。
    3. int    *(*f)();  这个就容易理解了,f是一个指向返回值是一个int类型的指针的函数的指针。
    4. int  *f[ ]; []的优先级比*的优先级要高,所以f是一个数组,然后类型是int指针。
    5. int   f()[] f是一个函数,返回值为整型数组(非法,c语言函数无法返回数组)
    6. int   f[]() f是一个函数的数组 非法(函数无法统一长度,所以不可能成为数组)
    7. int  (*f[])();  f首先是一个数组,然后f的元素是int型的指针,然后()又说明它势函数,所以f是一个函数指针的数组,返回的值是一个整数值
    8. int  *(*f[])(); f是返回int指针的函数的指针数组..(1 f是数组,f是指针数组,f是函数指针数组,f是返回值为int指针的函数指针数组
  2. 函数指针:编译器需要的是函数指针
  3. 函数指针的应用
    1. 回调函数
    2. 转移表请保证下标的合法
  4. 命令行参数  
  5. 字符串常量什么呢?“xyz”字符串常量实际上是个指针,指针值加上1,既是y
  6. *“xyz”  指针指向首个字符,解引用就是x
  7.   好吧间接访问  其实就是z

预处理器

  1. 预定义符号
  2.  

说实在的,书看过了很容易忘记,还是要经常复习复习,最主要的是要知道有那么个东西,忘记了不要紧,要用的时候知道有这么个东西就知道去哪找

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值