ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C语言-学习笔记 --《c primer plus》

2021-08-04 12:33:38  阅读:108  来源: 互联网

标签:__ 存储 函数 -- C语言 作用域 plus 链接 变量


C语言

1. C语言基础

  • 命名只能用字母、数字、下划线,名称第一位不能为数字。
  • 函数包含:函数原型、函数调用、函数定义。 函数原型可以省略参数名,函数定义中不可以。
  • 程序错误:语法错误、语义错误。
  • 两个很大的数据相减,浮点数损失精度更多。因为任何一个区间内都存在无穷个实数,计算机的浮点数不能表示区间内的所有值。浮点数通常是实际值的近似值,例如,7.0可能被存储为6.9999。
  • (1111)2=2**5 -1 二进制1111等于2的5次方减一。
  • 100的16进制(%x)表示0x64,八进制(%o)0144。
  • char grad='a'; 用单引号框起来的是字符对应的ASCII码。" "双引号表示字符串。
  • C语言中将字符常量视为int型,而非char型。char letter='B';中B对应为66,存在32位存储单元中,现在grade截取后八位放在8为存储单元中。
  • int 32位;float 32位,数值符号位1,指数位8(第一位为指数符号1),尾数位23,有6-7位有效数字。double b4位,符号1位,指数11位,尾数52位,有效数字15-16位。浮点型常量写法,如-1.56e3,3.4E5。没有后缀的浮点型,默认是double。
  • C语言数值类型分为整数类型、浮点数类型。使用可移植类型可以保证数据类型位数是自己要求的位数,屏蔽掉不同系统的差异。一般包含精确宽度整数类型(C90)、最快最小宽度类型(C99、C11)。
  • %zd z是修饰符、d是转换字符,修饰符不可以单独使用。
  • ++a是a先加1再计算,a++是运算结束后加1。
  • 形参中的char、short会自动升级成int,float会变成double。这是隐式类型装换,在使用时会自动进行裁切。主要是把所有的操作数转换为统一的长度,极大地简化了代码的生成,这样,压到堆栈中的参数都是同一长度的,所以运行时系统只需要知道参数的数目,而不需要知道它们的长度,是一种临时手段。
  • 条件运算符(?: 三元运算符)比if else更简洁。
  • 回显输入意味着用户输入的字符直接显示在屏幕上,无回显输入意味着击键后对应字符不显示。
  • 可使用<符号重定向输入流,使用>符号重定向输出流。
  • scanf 会把换行符留在输入队列。
  • 递归每次调用都会创建一组变量,使用内存更多,且由于函数每次调用会花费时间,所以执行速度更慢,但在某些场景下解决更简单(如处理倒序)。
  • C90不支持变长数组a[n](VLA,n为整型变量),C99支持VLA(不能使用static extern修饰),C11可选支持。
  • 字符串初始化用指针与字符数组的区别:1、数组名是常量,而指针名是变量。2、初始化数组把静态存储区的字符串拷贝到数组中,而初始化指针只把字符串的地址拷贝给指针。建议在把指针初始化为字符串字面量时使用const限定符。3、不修改字符串,不要用指针指向字符串,需要修改字符串用字符数组。
  • gets()、puts()在C11中被废弃,可用fgets()、fputs()、gets_s()(c11新增可选支持)替代。

2. 存储类别、链接和内存管理

  • 存储期描述了通过标识符访问的对象的生存期。分为:静态存储期、线程存储期、自动存储期、动态分配存储期(malloc、calloc)。
  • 静态存储期,它在程序执行期间一直存在。文件作用域变量具有静态存储期。块作用域变量也可以具有静态存储期,加上static即可。自动初始化为0。
  • 线程存储期用于并发程序设计,具有线程存储期的变量,从被声明时到线程结束一直存在。用关键字 _Thread_local声明时,每个线程都有一个私有备份。
  • 块作用域的变量通常具有自动存储期,进入这些块时,为这些变量分配内存,离开块时释放。
  • 标识符用于访问对象(储存值的一块内存),可以用作用域、链接描述标识符的可见性。
  • 作用域描述程序中可访问标识符的区域。分为块作用域、函数作用域、函数原型作用域和文件作用域。
  • 链接分为:外部链接、内部链接、无连接。具有块作用域、函数作用域、函数原型作用域的变量都是无链接,是私有的。具有文件作用域的变量可以使外链接(默认extern)或者内部链接(static)。
  • 自动变量是属于自动存储期的变量,具有自动存储期、块作用域且无链接。可显示使用auto(C++auto含义完全不同)。不会初始化。
  • 寄存器变量同自动变量,不过是把变量放在寄存器中。不保证在寄存器中,无法获取地址,数据类型有限(寄存器位数有限)。
  • 块作用域的静态变量,具有静态存储期的变量,用static声明。
  • 外部链接的静态变量,具有文件作用域,外部链接和静态存储期。用extern声明,只能初始化一次且必须在定义时进行。
  • C99和C11要求识别局部标识符的前63个字符和外部标识符的前31个字符。之前标准是前31和前6个。
  • 内部链接的静态变量,具有静态存储期、文件作用域和内部链接。用存储类别说明符static声明。
  • 存储类别说明符:auto、register、static、extern、_Thread_local、typedef。
  • 函数也有存储类别,使用static说明函数为模块私有,可以解决命名冲突,默认是extern。
  • 可以使用malloc、calloc(初始化为0)函数来自行分配内存,不过最后注意要free内存,防止内存泄漏。
  • restrict,只能用于指针,表明该指针是访问数据对象的唯一且初始的方式。
  • volatile限定符告知计算机,代理(其他程序)可以改变该变量的值。涉及到编译器的优化。
  • _Atomic类型限定符,用在多线程中,声明原子类型的变量,C11可选支持。

3. 文件输入输出

  • C把文件看作是一系列连续的字节,每个字节都能被单独处理。提供两种文件模式:文本模式、二进制模式。
  • fopen()的模式字符串,r、w、a、x(C11)。getc(fp)、putc(fp)是从指定文件中获取一个字符。需要fclose()关闭。
  • fseek()可以在打开的文件中,直接移动到任意字符。文件起始点模式有SEEK_SET、SEEK_CUR、SEEK_END。
  • ftell()返回文件中当前位置。
  • fgetpos()、fsetpos()是处理较大文件的新定位函数。
  • fread()、fwrite(),在要求不损失精度的条件下保存和恢复值,用函数采用二进制模式进行读写。缺点:不同的操作系统可能使用不同的二进制表示法,所以数据文件可能具有不可移植性;甚至一个操作系统,不同的编译设置也会导致不同的二进制布局。

4.C预处理器和C库

  • #define 来定义宏,包含明示常量、任何字符串、字符常量、类函数宏(宏带参数)、也可以为空,只做参数替换,不进行计算。替换部分可以用##将两个记号组合成一个记号、用#组合字符串、...与__VAR_ARGS__可用来自定义可变参数的宏,只能放在最后面。
  • #include会查看后面的文件名并把文件的内容包含到当前文件中,即替换源文件的#include指令。
  • 头文件中最常用的形式包含明示常量、宏函数、函数声明(函数原型)、结构模板声明、类型定义。
  • #undef 用于取消已定义的#indefine指令,也就是取消已经定义的宏。
  • 条件编译指令,#ifdef、#else、#endif,#ifdef max表示是否#define定义了MAX、或者包含了头文件,可以用来标记C语句块。与之相反的还有#ifndef、#else、#endif。主要用于防止多次包含头文件。
  • #if、#elif与if、else if相似,后面跟整型常量表达式,如果表达式为非零,则表达式为真。
  • 预定义宏:__DATE__,__FILE__,__LINE__,__STDC__,__STDC_HOSTED__,__STDC_version__,__TIME__,__func__。
  • #line 重置__FILE__和__LINE__报告的文件名和行号。
  • #error指令让预处理器发出一条错误信息,该消息包含指令中的文本。
  • #pragma编译指示,用于控制分配给自动变量的内存量、设置错误检查严格程度、启用非标准语言特性等。
  • _GENERIC泛型选择表达式,常用作#define宏定义的一部分。
  • 内联函数(C99),标准规定具有内部链接的函数可以成为内联函数,最简单的使用方法是使用函数说明符inline和存储类别符。可以放在头文件中。因为是直接替换函数代码,所以可以避免函数调用的开销(建立调用、传递参数、跳转到函数代码并返回)。C99
  • _Noreturn,这是第二个函数说明符,表明函数调用后,不返回主调函数。exit()和abort()都使用此声明。
  • atexit(),在调用exit()退出时,调用最后注册的函数。
  • assert(),接受一个整型表达式作为参数(一般为条件表达式、逻辑表达式),如果表达式为假(非零),assert()宏就在标准错误流(stderr)中写入一条错误信息,并调用abort()终止程序。可用#define NDEBUG禁用assert()。是在运行时检查。
  • _Static_assert(),可以在编译时检查assert()表达式,可以让程序无法通过编译。可以出现在函数中。C11
  • 在stdarg.h中,提供一些变参宏,即该宏可以接受可变数量的参数。包含有:va_start()、va_arg()、va_end()、va_copy()、va_list等。

5.高级数据表示

  • 使用抽象数据类型方法编程:
    1. ADT(抽象数据类型),以抽象、通用的方式描述一个类型,包括该类型的操作。
    2. 设计函数接口表示这个新类型。
    3. 编写具体代码实现这个接口。
  • 数组的优点:C直接支持、提供随机访问;缺点:在编译时确定大小、插入和删除很费时。
  • 链表的优点:运行时确定大小、快速插入和删除元素;缺点:不能随机访问、用户必须提供编程支持。
  • 随机访问表示同一时间访问一组序列中的一个随意组件。对数组而言,可以使用下标直接访问该数组中的任意元素。对链表而言,必须从首节点开始逐个移动到要访问到的节点,是顺序访问。
  • 二叉查找树树是一种结合了二分查找策略的链接结构,是一种有序的二叉树。为了使左右子树更加平衡,可以使用AVL(平衡二叉树)。

标签:__,存储,函数,--,C语言,作用域,plus,链接,变量
来源: https://www.cnblogs.com/oniisan/p/cprimerplus.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有