• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 关于《C和指针》的学习笔记

关于《C和指针》的学习笔记

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了关于《C和指针》的学习笔记等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

  有了之前的基础,此文只是把一些以前没有注意到的和值得学习的知识做一个记录。

第一章

  作者认为使用#if 0 .... #endif比用/*和*/好,因为后者不能嵌套。但是对于//并没有说明。

第二章  

  三字母词,用两个问号加一个符号表示另一个符号,比较类似于转义字符。查阅了一些资料,它的使用与编译器有关,了解即可,防止字符串常量被错误的解释。

??) ==> ]   ??> ==> }   ??/ ==> \ 

??! ==> |   ??' ==> ^    ??- ==> ~ 
</div>
  对于嵌套较深的函数,作者建议把它分成几个函数来实现,不至于使用Tab缩进过多。

第三章  数据

  对于static的复杂用法,当它用于函数定义或代码块之外的变量声明时,static用于修改标识符的连接属性,从external改为internal,但标识符的存储类型和作用域不受影响。用这种方式声明的函数或变量只能在声明它们的源文件中访问。当它用于代码块内部的变量声明时,static用于修改变量的存储类型,从自动变量修改为静态变量,但变量的链接属性和作用域不受影响。用这种方式声明的变量在程序执行之前创建,并在程序的整个执行期间一直存在,而不是每次在代码块开始执行时创建,在代码块执行完毕后销毁。

 

第五章  操作符和表达式

  移位操作,当移动的位数为负值时,具体的结果与编译器有关或者是未定义的,比如a<<-5可能是左移27位。

  形如a+=1的操作效率比a=a+1高,等价的a[ 2 * (y - 6*f(x)) ]=a[ 2 * (y- 6*f(x))] + 1与a[ 2 * (y- 6*f(x))] += 1相比,后者不用重复计算下标。

  sizeof x的形式是允许的。sizeof()并不对表达式求值,因此sizeof(a=b+1)中的a没有赋值。

  访问指向结构的指针的成员时只用->。

 

第六章  指针

  未初始化的指针会导致错误。int *a; *a = 12,这使a指向的地址的内容被修改,结果是无法预料的。

  作者认为在诸如搜索元素而未找到时返回值为NULL指针虽然是C的常用技巧,但违背了软件工程的原则:“用一个单一的值表示两种不同的意思是件危险的事,因为将来很容易无法弄清哪个才是它的真正用意”。安全的策略是返回两个值,表示是否成功的状态值和查找成功时所查找到的元素值。

 

第七章  函数

  无参数的函数原型声明应该写作这样:int func(void); 目的是不与旧式风格声明混淆。

  递归解决问题比非递归更为清晰,对于一个复杂问题,难以用迭代形式实现时,递归实现的简洁性可以补偿它所带来的开销。Fibonacci是一个常见的递归的例子,但冗余计算很多,开销太大,实际上并不如迭代实现。

long fibonacci(int n)
{
    long result;
    long previous_result;
    long next_older_result;

    result = previous_result = 1;

    while( n > 2) {
       n -= 1;
       next_older_result = previous_result;
       previous_result = result;
       result = previous_result + next_older_result;
     }
    return result;
}
</div>
  可变参数列表的使用:头文件stdarg.h,其中声明了一个类型va_list和三个宏va_start、va_arg、va_end。通过声明va_list类型的变量与这几个宏配合使用,访问参数的值。函数声明了一个var_arg的变量用于访问参数列表未确定部分,它通过va_start初始化。第1个参数是va_list变量的名字,第2个参数是省略号前最后一个有名字的参数。初始化过程把var_arg变量指向可变参数部分第1个参数。va_arg接受两个参数:va_list和参数列表的下一个参数的类型。va_arg返回参数的值并使var_arg指向下一个可变参数。访问完毕调用va_end。

float average( int n_values, ... )
{
    va_list var_arg;
    int count;
    float sum = 0;

    /*准备访问可变参数*/
    va_start( var_arg, n_values) ;

    /*添加取自可变参数列表的值*/
    for (count = 0; count < n_values; count += 1) {
        sum += va_arg( var_arg, int);
    }

    /*完成处理可变参数*/
    va_end(var_arg);
    return sum/n_values;
}
</div>
  可变参数的宏并不能判断参数数量和参数类型,而后者可能会造成缺省参数类型的提升。解决这两个问题的方法是使用命名参数,也就是可变参数列表中总有一个有名字的参数的原因。

 

第八章  数组

  int array[10];int *ap =array+2;在这之后,ap[0]在C里是合法的,它等同于array[2],ap[-1]同样是合法的,即array[1]。

  指针比数组更有效率的场合:for循环的ap++比循环体中的array[a] = 0有效率,前者的乘法计算只有一次,用于1与数据类型长度相乘,而后者每次都需要进行计算。

/* 使用指针 */
int array[10], *ap;
for ( ap = array ; ap< array + 10; ap ++ )
    *ap = 0;
</div>
  数组特别是庞大的数组的初始化时间可能非常可观,因此当数组的初始化局部于一个函数或代码块时,应当考虑程序每次都对其进行重新初始化是否值得。若否,把数组声明为static。

  使用指针访问多维数组的方法,例如对于数组int matrix[3][10],声明int *mp = matrix是错误的,因为matrix并非一个指向整型的指针,而是一个指向整型数组的指针。int (*p)[10] = matrix是可以的,p指向matrix第一行,实现对数组的逐行访问。如果需要逐个访问,则使用int *pi = &matrix[0][0]或int *pi = matrix[0],使它指向第一个元素。而 int (*p)[] = matrix;是不正确的,它的值根据空数组的长度调整,这一错误有的编译器不能捕捉到。函数传参数类似。

  多维数组显式初始化,只有第一维能够推算出,其他维不能省略。

 

第九章  字符串、字符和字节

   无符号数的谨慎使用:strlen返回无符号数,因此if(strlen(x) - strlen(y)>=0) ...永远是真。这种情况下应该写为if(strlen(x)>=strlen(y)) ...或者采用强制类型转换把其转为int。

  strtok保存它所处理的函数的局部状态信息,因此不能用它同时解析两个字符串。

  字符串函数遇到NULL字节结束操作,想要处理非字符串数据时不受到这个限制,可以使用另一组相关的函数:memcpy、memmove、memcmp、memchr、memset。

 

第十章  结构和联合

  参数为结构的函数,传递指针比传值调用更高效,这是因为后者需要建立一份结构的拷贝。f(type_struct *s){s->x};调用即为f(&s)。如果对这个结构的成员访问次数超过3次,声明为寄存器变量会更加有效。为了避免不适当的修改,可以把参数声明为const,将返回值赋给原结构(或它的一个成员)。

  位段只是进行了简单的了解,它是一种指定了成员长度的特殊结构。

 

第十三章  高级指针话题

  回调函数的使用可以解决类似于比较不明类型数据的问题,这里也是第一次系统地认识回调函数。

 

第十四章  预处理器

  消除多重包含的危险的方法,在每个头文件写入以下内容:
代码如下:</div>

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2017-05-28C++设计模式之观察者模式
  • 2017-05-28C语言基础之格式化输出控制长度
  • 2017-05-28VC实现屏幕截词功能的方法详解
  • 2017-05-28全面了解结构体、联合体和枚举类型
  • 2017-05-28关于C/C++中static关键字的作用总结
  • 2017-05-28C语言中的参数传递机制详解
  • 2017-05-28C语言自动生成enum值和名字映射代码
  • 2017-05-28学习C语言要掌握的几个库
  • 2017-05-28C++实现在文本中找出某个单词的位置信息
  • 2017-05-28C++ sizeof 实例解析

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 详解C语言求两个数的最大公约数及最小公倍数的方法
    • 浅析C++11中的右值引用、转移语义和完美转发
    • VC WinExec打开指定程序或者文件的方法
    • C++的虚析构详解及实例代码
    • C++ 数据结构链表的实现代码
    • C++中extern "C"的用法
    • C语言中的强符号和弱符号介绍
    • Microsoft Visual C++ 6.0开发环境搭建教程
    • 简述C语言中system()函数与vfork()函数的使用方法
    • c语言实现把文件中数据读取并存到数组中

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有