C语言概述

  • 标准C库
    ANSI C共包括15个头文件。
    1995年,Normative Addendum 1(NA1)批准了3个头文件(iso646.h、wchar.h和wctype.h)增加到C标准函数库中。
    C99标准增加6个头文件:
    (complex.h、fenv.h、inttypes.h、stdbool.h、stdint.h和tgmath.h)。C11标准中又新增了5个头文件:
    (stdalign.h、stdatomic.h、stdnoreturn.h、threads.h和uchar.h)。

  • 至此, C标准函数库共有29个头文件:

C语言特点

  1. C语言简洁、紧凑、灵活。C语言的核心内容很少,只有32个关键字,9种控制语句;程序书写格式自由,压缩了一切不必要的成分。
  2. 表达方式简练、实用。C语言有一套强有力的运算符,达44种,可以构造出多种形式的表达式,用一个表达式就可以实现其它语言可能要用多条语句才能实现的功能。
  3. 具有丰富的数据类型。数据类型越多,数据的表达能力就越强。C语言具有现代语言的各种数据类型,如:字符型、整型、实型、数组、指针、结构体和共用体等。可以实现诸如链表、堆栈、队列、树等各种复杂的数据结构。其中指针使参数的传递简单、迅速,节省内存。
  4. 具有低级语言的特点。具有与汇编语言相近的功能和描述方法,如地址运算、二进制数位运算等,对硬件端口等资源直接操作,可充分使用计算机资源。因此,C语言既具有高级语言便于学习和掌握的特点,又具有机器语言或汇编语言对硬件的操作能力。所以,C语言既可以作为系统描述语言,又可以作为通用的程序设计语言。
  5. 是一种结构化语言,适合于大型程序的模块化设计。 C语言提供了编写结构化程序的基本控制语句,如if~else语句、switch语句、while语句、do~while语句等。C程序是函数的集合,函数是构成C程序的基本单位,每个函数具有独立的功能,函数之间通过参数传递数据。除了用户编写的函数外,不同的编译系统、操作系统都相伴还提供了大量的库函数供用户使用,如输入输出函数、数学函数、字符串处理函数等,灵活使用库函数可以简化程序的设计。
  6. 各种版本的编译系统都提供了预处理命令和预处理程序。 预处理扩展了C语言的功能,提高了程序的可移植性,为大型程序的调试提供了方便。
  7. 可移植性好。程序可以从一个环境不经改动或稍加改动就可移植到另一个完全不同的环境中运行。这是因为系统库函数和预处理程序将可能出现的与机器有关的因素与源程序隔开,这就容易在不同的C编译系统之间重新定义有关内容。
  8. 生成的目标代码质量高。由C源程序得到的目标代码的运行效率比用汇编语言写的也不过只低10%到20%,可充分发挥机器的效率。
  9. C语言语法限制不严,程序设计自由度大。 C程序在运行时不做诸如数组下标越界和变量类型兼容性等检查,而是由编程者自己保证程序的正确性。C语言几乎允许所有的数据类型的转换,字符型和整型可以自由混合使用,所有类型均可作逻辑型,可自己定义新的类型,还可以把某类型强制转换为指定的类型。实际上,这使编程者有了更大的自主性,能编写出灵活、优质的程序,同时也给初学者增加了一定的难度。所以,只有在熟练掌握C语言程序设计后,才能体会出其灵活的特性。
    • 通过上述的介绍,已经了解了C语言的若干特点。C语言虽然是一种优秀的计算机程序设计语言,但也存在以下的一些缺点,了解这些缺点,才能够在实际使用中扬长避短。
  • C程序的错误更隐蔽。C语言的灵活性使得用它编写程序时更容易出错,而且C语言的编译器不检查这样的错误。与汇编语言类似,需要程序运行是才能发现这些逻辑错误。C语言还会有一些隐患,需要程序员重视,比如将比较的"==“写成赋值”=",语法上没有错误,这样的逻辑错误不易发现,要找出来往往十分费时。
  • C程序有时会难以理解。C语言语法成分相对简单,是一种小型语言。但是,其数据类型多,运算符丰富且结合性多样,使得对其理解有一定的难度。有关运算符和结合性,人们最常说的一句话是“先乘除,后加减,同级运算从左到右”,但是C语言远比这要复杂。发明C语言时,为了减少字符输入,C语言比较简明,同时也使得C语言可以写出常人几乎无法理解的程序。
  • C程序有时会难以修改。考虑到程序规模的大型化或者说巨型化,现代编程语言通常会提供“类”和“包”之类的语言特性,这样的特性可以将程序分解成更加易于管理的模块。然而C语言缺少这样的特性,维护大型程序显得比较困难。 早期的计算机语言有BASIC语言、Fortran语言、ALGOL语言、COBOL语言和Pascal语言等,近来使用的人相对要少得多,除非是既有的软件系统使用这些语言,或者一些人想使用现成的程序或软件,才会使用这些语言。 现在的软件开发中更多地使用C++语言和Java语言,在开发Web应用软件时则会使用JSP语言和PHP语言等。随着面向对象技术的广泛普及,Java语言受到很多人的青睐,这是由于Java语言具有编程效率高,降低软件开发成本,不需要考虑存储的分配与回收等程序细节,编写出来的程序更具有健壮性,但是也一定程度上付出了运行效率的代价。C++语言则介于C语言和Java语言之间,也是面向对象的计算机语言,同时具有编程效率高和运行速度快的特点。 C语言是一种过程性的语言,职业的程序员或软件开发人员应该学习一下该计算机语言。这是因为,C语言可以代替机器语言或汇编语言编写运行速度快的程序;对于单片机应用、嵌入式系统和通信软件等是不可替代的;C语言的指针与计算机硬件的地址具有异曲同工之处,是了解计算本质的钥匙;通过C语言相关的存储分配函数,可以深入了解计算机存储分配的原理。

C语言发展史

K&R C
C89
C90
C99
C11
C18
C2x

第一章 初识C语言

  • 源程序是人们作为字符序列创建出来的,不能直接执行,需要编译(翻译),将其变为可执行程序
  • /* 和*/ 之间的部分是注释。注释可以有多行,用简洁的话来注释,方便阅读程序的人参考,包括自己,// 一样的作用。

注释是写给程序员看的,不是写给电脑看的。

C语言注释方法有两种:

多行注释: /* 注释内容 */

单行注释: //注释一行

  • C语言主函数代码格式:
#includeABCtdio.h>
int main()
{...........return 0;
}
  • 不要把stdio.h和studio.h 混淆
  • 语句的末尾要加分号 “;”。
  • 执行程序的时候{ 和 }之间的语句会按顺序执行。
  • 换行符 \n
    响铃符 \a
    我们一般用反斜杠 \ 代替货币符号¥
  • 字符串常量
    “ABC”,这样用双引号括起来的一连串排列的文字,叫做字符串常量。
  • int是整型
  • 变量在生成的时候会被放入不确定的值。因此声明变量的时候,除了特别要求以外,一定要为其赋初始值,进行初始化。
  • 初始化和赋值的区别
    初始化:在生成变量的时候放入数值
    赋值:在已生成的变量中放入数值
int abc = 123;  //初始化
int xyz;
xyz = 57;  //赋值
  • 可以一次声明多个变量,要用逗号分隔变量名,例如:

int a,b;

  • 格式化输出语句,也可以说是占位输出,是将各种类型的数据按照格式化后的类型及指定的位置从计算机上显示。

其格式为:printf(“输出格式符”,输出项);

printf("面积为%d。\a\n",width * height)

转换格式 %d 指定了读取十进制数

  • 用于显示的函数有 printfputs
  • scanf 函数是读取通过键盘输入的数值并将其存储在变量中的函数。使用scanf 函数时,变量名前要加上 && 叫做取地址符

第二章 运算和数据类型

  • 可以进行运算的符号叫做运算符。
    根据运算对象——操作数的个数,运算符可以分为三类:
    单目运算符,双目计算符,三目计算符

  • 单目‘+’运算符的功能就是输出操作数本身的值,单目‘-’运算符的功能就是对运算符进行符号去反操作

  • 将右操作数的值赋给左操作数的‘= ’,称为 (基本)赋值运算符

  • 由变量和常量,以及连接他们的运算符所构成的就是表达式

  • 在表达式后面加上分号‘;’,就形成了表达式语句。

  • 数据类型实际上就是一个隐藏着各种属性的设计蓝图(可以看成做章鱼小丸子用的模具),包含某个类型的对象(变量),就是根据这个设计蓝图创建出来的实体,(相当于用模具做出来的章鱼小丸子)。

  • int
    整数型,只能表示整数。即使被赋值给含有小数的值,小数部分也会被舍去。
    像5和37这样的就是整数常量。

  • double
    浮点型,只能表示浮点数(带有小数部分的实数值)。像3.14这样包含小数的常量,称为浮点型常量。

  • 如果一个运算中有不同类型的操作数,就会进行 ‘隐式类型转换’
    运算对象——操作数的类型不同时,较小的数据类型的操作数就会转换为较大的数据类型,然后再进行运算。
    因此,当一个运算中既有int类型又有double类型的时候,各操作数都会被转换成double类型。

  • 若要将某个表达式的值转换为别的数据类型所对应的值的时候,需要使用类型转换符() 进行转换。

printf("平均值 = %f\n\n",(double) (a + b)/2);//这里的就是类型转化表达式
  • 当用printf函数来显示double类型的值时,转换说明是 %f;当用scanf函数来读取时,转换说明是 %lf
  • 转换说明由0标志,最小字段宽度,精度,转换说明符构成。
  • 若要在printf函数中显示%字符,需要在格式化字符中写入%%

基本数据类型的取值范围

1.比特位

  • CPU能读懂的最小单位是:比特位,bit,b。每个比特位只能存放二进制数,即0和1.

2.字节

  • 内存机构最小寻址单位:字节,Byte,B

注:1Byte = 8 bit

3.符号位

  • 存放signed类型的存储单元中,左边第一位表示符号位。如果该位为0,表示该整数是一个正数;如果该位为1,表示该整数是一个负数。
  • 一个32位的整型变量,除去左边第一位符号位,剩下表示值的只有31个比特位。

4.补码

  • 正数的补码是该数的二进制形式。
  • 负数的补码需要通过以下几步获得:

(1)先取得该数的绝对值的二进制形式

(2)再将第1步的值按位取反(除符号位)

(3)最后将第2步的值加1

5.取值范围

整数的类型

int

  • 整型的使用

    • 各种类型的存储大小与操作系统、 系统位数和编译器有关 ,目前通用的以64位系统为主。
    • 在实际工作中, c程序通常运行在linux/unix 操作系统下.大众:使用windows10(64位)
    • C语言的整型类型, 分为有符号 signed 和无符号 unsigned 两种, 默认是 signed
    • C程序中整型常声明为int型, 除非不足以表示大数, 才使用long long
  • bit(位): 计算机中的最小存储单位。 byte(字节):计算机中基本存储单元。
    • 1byte = 8bit [二进制再详细说, 简单举例一个 short 3 和 int 3 ]
    • short 3 在内存中占有 2字节
    • int 3 在内存中占有 4个字节

浮点类型

  • 浮点型使用细节
    1.浮点型常量默认为double型 , 声明float型常量时, 须后加‘f’或‘F’。
    2.浮点型常量有两种表示形式

    • 十进制数形式:如: 5.12 512.0f .512 (必须有小数点)
    • 科学计数法形式:如: 5.12e2 、 5.12E-2

    3.通常情况下,应该使用double型,因为它比float型更精确。
    4.printf("d1=%f ", d1); // 在输出时,默认保留 小数点6位

字符类型

  • 基本介绍
    字符类型可以表示单个字符,字符类型是char, char是1个字节(可以存字母或者数字),多个字符称为字符串, 在C语言中 使用 char数组 表示,数组不是基本数据类型,而是构造类型。

字符类型使用细节

1.字符常量是用单引号(‘’)括起来的单个字符。 例如: char c1 =‘a’; char c3 = ‘9’;

2.C中还允许使用转义字符‘\’来将其后的字符转变为特殊字符型常量。例如: char c3 = ‘\n’; // '\n’表示换行符

3.在C中, char的本质是一个整数,在输出时,是ASCII码对应的字符。

4.可以直接给char赋一个整数,然后输出时,会按照对应的ASCII 字符输出 [97]

5.char类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码.

C语言变量的生命周期和作用域

C语言中常量

  • C编程中的常量是一些固定的值,它在整个程序运行过程中无法被改变

字面常量

  • 字面常量是直接写出的固定值,它包含C语言中可用的数据类型,可分为整型常量,字符常量等。如:9.9,“hello” 等就属于这一类常量。

const修饰的常变量

有的时候我们希望定义这么一种变量:值不能被修改,在整个作用域中都维持原值。为了满足用户需求,C语言标准提供了const关键字。在定义变量的同时,在变量名之前加上const修饰。

int main()
{const a = 1;//const 修饰的常变量return 0;
}
  • const 修饰的常变量,本质上是变量。
  • 但是具有常属性,所以不能更改

define定义的标识符常量

  • C语言提供了 ** #define ** 命令定义标识符常量,该标识符常量在程序中是个定值,通常用于代表数组容量或涉及数学的常量等。
#define PI 3.14159
#define SIZE 10    // 此处SIZE代表数组元素个数
int main()
{int arr[SIZE]={0};return 0;
}

如需修改数组大小,只需将SIZE所代表的值修改即可,十分方便

枚举常量

  • 日常生活中有一些代表实际意义的常量,有这么一个特点:数值较小且为非负整数。如一周有7天等。C语言提供了一种枚举(Enum)类型,能够列出所有可能会用到的取值,并给它们取一个名字。
int main()
{enum Sex{//枚举常量     性别MALE, FEMALE,SECRET};enum Sex s = FEMALE;  //利用枚举常量给变量赋值printf("%d\n", MALE);printf("%d\n", FEMALE);printf("%d\n",SECRET);return 0;
}
  • 在使用枚举常量的时候,需要注意以下几点:

    • 不能对枚举常量赋值,只能将它们的值赋给其他的变量。
    • 不能再定义与枚举常量名字相同的变量。
    • 不能用 & 取得它们的地址。

第三章 运算符和表达式

赋值运算符

  • 赋值运算符支持的是C语言的基本数据类型,包括int,char,double。字符串(字符数组)不能使用赋值运算符。

算术运算符

  • 变量的自增或自减有两种写法:

    变量名++; // 表示在本次使用变量后再自增;

    ++变量名; // 表示在本次使用变量前自增;

    变量名 - -; // 表示在本次使用变量后再自增;

    – - 变量名; // 表示在本次使用变量前自减;

关系运算符

  • 注意
    在C语言中‘=’表示赋值,而‘==’才表示判断,不能混淆。

逻辑运算符

逗号运算符

  • 用法概述
    C语言中","也是一种运算符,称为逗号运算符。其功能是将两个或多个表达式连接起来组成一个表达式。具体形式如下:

表达式1,表达式2,表达式3,…,表达式n

  • 逗号表达式本身并不复杂,逗号表达式遵循一下三点特性

    1.逗号表达式从表达式1开始顺序从左向右执行;
    2.其逗号表达式最后的值为最后一个表达式的值;
    3.逗号运算的优先级最低,也就说明与其他运算符结合使用的时候,在没有括号的情况下逗号运算符最后才执行。

条件运算符

  • 三目运算符也叫条件运算符、三元运算符,是由一个问号和一个冒号组成。

语法:

表达式1?表达式2:表达式3;

语义:

先执行表达式1,如果表达式1的结果如果为真,那么执行表达式2,并且这个整体的运算式的结果是表达式2的结果;如果表达式1的结果如果为假,执行表达式3,运算式的结果是表达式3的结果。

int a,b,c;a=7;b=6;c=(a>b)?a:b;

等同于

  if (a>b) c=a;else c=b;

sizeof 运算符

语法

  • sizeof有三种语法形式:

    1、sizeof(object); //sizeof(对象);

    2、sizeof(type_name); //sizeof(类型);

    3、sizeof object; //sizeof 对象;

  • 基本数据类型的sizeof
    等于各数据类型在内存中所占的字节数。这里的基本数据类型指的是short、int、long、float等简单的内置数据类型,由于它们和系统相关,所以取值在不同系统下可能会不同,可移植性较差。

  • 指针变量的sizeof
    等于计算机内部地址总线的宽度。所以在32位计算机中,一个指针变量的返回值必定是4(注意结果是以字节为单位)。

    • 指针变量的sizeof值与指着所指的对象没有任何关系。
  • 数组的sizeof
    数组的sizeof值等于数组所占用的内存字节数。

  • 结构体的sizeof
    sizeof的结果等于对象或者类型所占的内存字节数

第四章 语句和控制流

  • 一个函数包含声明部分和执行部分。执行部分由语句组成,经编译后产生机器指令。声明部分不是语句,不产生机器指令。

语句和程序块

语句分类

C语言中的语句分为以下几类:

  • (1).
    控制语句:
    条件语句:if(表达式) … else if(表达式) … else …
    循环语句:
    (1). for(表达式1; 表达式2; 表达式3) …。在C99标准中允许表达式1定义变量并赋予初值。推荐在这里给仅在循环中用到的变量定义,因为这样能缩短变量的作用域
    (2). while(表达式) …
    (3). do … while(表达式);(注意最后有分号)
    多层循环嵌套时,一般长循环放在内层,短循环放在外层
    跳过本次循环语句:continue
    结束switch或循环语句:break
    多分支选择语句:switch。

swich语句的模型

switch(整型数据(包括枚举型)或字符型数据) {
case 常量1: 语句1; break;
case 常量2: 语句2; break;
case 常量3:
case 常量4: 语句3; break;//此时常量3和常量4都进入到语句3

default: 语句n;(没有default时不符合则跳过)
}

函数返回语句:return
转向语句:goto。先在程序某处添加标记,如"mark: ",然后使用"goto mark;"跳转。

  • (2)函数调用语句
    如printf(“Hello world.”);

  • (3). 表达式语句
    如赋值表达式a=3;,++i;等

  • (4). 空语句
    直接只有一个分号的一行语句。

  • (5). 复合语句
    用{}将语句和声明括起来的复合语句,也称语句块。

输入和输出语句

  • C语言中常用语句是输入和输出语句 (scanf)(printf)

(1). printf
一般形式为printf(格式控制,输出表列)

  • d格式符。用来输出有符号十进制整数。%5d表示数据占据5列且数据靠右,若想靠左则为%-5d。但%+d则表示输出整数前的正负号。长整型则为%ld,双长整型为%lld。l可放在d、o、x、u前。而在scanf中%5d则表示只读取前5位整数
  • c格式符。用来输出一个字符
  • s格式符。用来输出一个字符串。%5s在printf中表示只输出前5个字符,在scanf中表示只读取前5个字符.
  • f格式符。用来输出实数.
    (1). 基本型用%f。实数部分全部输出,小数部分输出6位
    (2). 指定数据宽度和小数位数%m.nf。如果n为0则不会输出小数点。注意其中m是指包含小数点在内的整个浮点数长度而不单单指整数部分
  • e格式符。用来输出指数形式实数。同样可以用%m.ne形式声明。也可用写成%E,此时输出指数中为大写E
  • i 格式符。在 printf 中没有区别,在 scanf 时,%d 只与十进制形式的整数相匹配;而%i 则可以匹配八进制、十进制、十六进制表示的整数。 如输入的数字有前缀 0(018、025),%i会把它当作八进制数来处理,如果有前缀0x (0x54),它将以十六进制来处理
  • o格式符。连同符号位一起以八进制整数形式输出
  • x格式符。连同符号位一起以十六进制整数形式输出。%X时以大写形式输出
  • u格式符。用来输出无符号整数
  • g格式符。用来输出浮点数,并由系统自动选择为f格式或e格式输出。%G时以大写形式输出
  • p格式符。用来输出地址
    (2). scanf
    一般形式为scanf(格式控制,地址表列)
    其中,l可用于输入长整型数据如ld、lo、lx、lu以及double型数据lf、le。h可用于输入短整型数据如hd、ho、hx
    在scanf(“a=%d, b=%d”, &a, &b);中输入则必须为a=1, b=2。若为scanf(“a=%d b=%d”, &a, &b);则a=1与b=2之间必须要有1个以上的空白字符
    scanf和printf函数都有返回值,scanf返回正确读入了多少个变量,printf返回输出了包括换行符在内的有多少个字符。

(2)字符输入输出

  • putchar( c )。用于输出字符变量c。若c为整数则当ASCII码处理
  • c = getchar()
    用于输入一个字符,包括控制字符。
    注意getchar函数返回的不是char类型而是int类型
    此时有可能出现潜在错误。一般用法为while((a = getchar() && a!=EOF) != ‘\n’) { }。EOF是指检测文件尾,在头文件中通过宏定义定义值为-1。键盘输入EOF其实是命令行环境遗留下来的,但是很多系统支持仿真的EOF,如用Ctrl+D(Linux系统)或Ctrl+Z(Windows系统)来模拟输入EOF。

判断语句(if,swich语句)

一、if(…) {…}
1.一般形式:
if (表达式) {语句;}

表达式:
1.用非 0 值表示真,用 0 表示假;
2.if(flag) 相当于 if(flag!=0);
3.浮点数无法与 0 比较,只能用近似的值比较;例: 1e-6 等于1x10的-6次方可以看成0来使用;

2.用于单分支选择结构;
3.如含有交叉关系,使用并列的if语句;

例:输出两个整数中的最大值

#include <stdio.h>
void main()
{int a,b;printf("请输入两个整数:");scanf("%d %d",&a,&b);if(a>b){printf("max = %d\n",a);}if(a<b){printf("max = %d\n",b);}
}

二、if(…) {…} else {…}

例:输出两个整数中的最大值


//对非法字符进行检查和处理
#include <stdio.h>
void main()
{int a,b,max,data;printf("Input a,b:");data = scanf(" %d,%d",&a,&b);/*记录scanf()的返回值;*/if(data!=2)/*根据scanf()的返回值判断输入数据个数或者格式是否错误*/{printf("格式输入错误!");fflush(stdin);/*清除输入缓冲区中的错误内容(fflush()可能带来可移植性的问题)*/}else{max = a>b?a:b;/*三目运算符(a>b值为真则输出a的值,反之输出b的值)*/printf("%d\n",max);}}

三、if(…) {…} else if(…) {…} … else if(…) {…} else {…}

例:判断字符

#include <stdio.h>
void main()
{char ch;printf("请输入一个字符:");ch = getchar();/*getchar、putchar专门用于字符输入输出;getchar()写法上要写为 变量 = getchar();putchar()用法为putchar(变量);putchar('\n')输出一个控制符;putchar('字母/字符');输出字母/字符;*/if(ch<=31){printf("这是一个控制字符或通讯专用字符!\n");}else if(ch >= '0' && ch <= '9'){printf("这是一个数字!\n");}else if(ch >= 'A' && ch <= 'Z'){printf("这是一个大写字母!\n");}else if(ch >= 'a' && ch <= 'z'){printf("这是一个小写字母!\n");}else{printf("这是其他字符!\n");}
}

四、switch() {case …: …; case …: …; … default: …;}

switch语句相当于多个if-else语句;
(表达式)只能是char型或者int型;
case 后面至少要有一个空格,常量后面是冒号
(表达式)与 常量类型要保持一致;
记得记得记得 在需要跳出的时候,在语句后面加上break;

例:简单的加减乘除

#include <stdio.h>
void main()
{double a,b;char ch;printf("Input a(+ - * /)b:");scanf("%f%c%f",&a,&ch,&b);switch(ch){case '+':printf("%f%c%f=%.2f\n",a,ch,b,a+b);/*%.2f表示精度,可以理解为保留两位小数*/break;case '-':printf("%f%c%f=%.2f\n",a,ch,b,a-b);break;case '*':case 'X':case 'x':printf("%f%c%f=%.2f\n",a,ch,b,a*b);/*输入"x" "X" "*" 都执行这一条语句;不加break,会顺语句执行*/break;case '/':printf("%f%c%f=%.2f\n",a,ch,b,a/b);break;default:printf("请输入正确算式!\n");}
}

循环语句

  • C语言中提供了三种循环语句分别是:
    while语句do while语句for语句

while循环

while语句的执行步骤,首先计算控制表达式的值,如果表达式的值不为0(为真),则执行循环体,接着再次判断控制表达式,如果其值不为0,再次执行循环体。执行这个步骤直到控制表达式的值为0时停止。
如果while的控制表达式一直不为0,那么循环将一直进行下去,称为无限循环。这样的循环在循环体中都包含break,goto,return或者导致程序终止的函数(如exit等),以在适当的时机终止程序。

#include <stdio.h>int main()
{int i = 1;int sum = 0;while(1){if ( i > 50)break;sum += i;i++;}printf("1到50之间(包括1和50)的整数和为%d\n", sum);return 0;
}

do……while循环语句

do while语句与while语句非常相似,只不过do while语句在每次执行完循环体之后对控制表达式进行判断的,因此do
while语句的循环体至少会执行一次,而while语句的循环体可能一次都不被执行。

do while循环的执行步骤如下:首先执行循环体,再计算控制表达式的值,如果表达式的值非零再继续执行循环体,然后再次判断表达式的值。这个过程持续进行,知道控制表达式的值为0,终止do while语句执行。

  • 建议对do while的循环体都使用大括号包裹起来,因为大括号会使do while语句被误认为是while语句。
#include <stdio.h>int main()
{int i = 1;int sum = 0;do{sum += i;i++;}while(i <= 50);printf("1和50之间(包括1和50)的整数之和为%d\n", sum);return 0;
}

for语句

for语句的执行步骤是:首先执行表达式1进行初始化,然后判断表达式2的值是否为真,若为真,则执行循环体,然后执行表达式3.随后再次对表达式2的值进行判断,若为真,则再次执行循环体和表达式3,依次循环直到表达式2的值为0为止。

for语句的3个表达式都可以省略,若省略表达式1,则在执行循环前没有初始化的操作;若省略第三个表达式,则执行完循环体后,没有再需要执行的语句,循环体确保循环能够在有限时间内终止;若省略第二个表达式,则每次判断都默认为真,除非在循环体内使用break,goto和程序终止函数外,循环不会停止。

#include <stdio.h>int main()
{int sum = 0;int i;for (i = 1; i <= 50; i++){sum += i;}printf("1和50之间(包括1和50)的整数之和为%d\n", sum);return 0;
}

循环中的跳转语句

  • break,continue,goto语句

break语句

  • break语句在循环体的中间设置退出点,用以跳出while,do while和for循环,直接执行循环语句后面的语句
    除此之外,break语句还用于switch语句,用以跳出switch语句而直接执行switch语句后面的语句。对于嵌套的循环语句和(或)switch语句,break只能跳过其所在的那层循环或switch语句。

continue语句

  • continue语句并不跳出循环,而是将程序执行正好转移到循环体末尾处,跳过本次循环中循环体余下的内容。continue语句只能用于循环体中。
#include <stdio.h>int main()
{int n = 0;int sum = 0;while (n < 10){int i = 0;scanf("%d", &i);if (i == 0)continue;// 只是跳出本次循环sum += i;n++;}printf("以上十个非零数的和为:%d\n", sum);return 0;
}

goto语句

  • goto语句不仅可以用在循环体中,还可以用在程序的任何位置。与continue和break不同,它可以跳转到同一个函数中任何有标记的语句处。goto依赖于定义在语句开头的标识符,其形式为:标识符 : 语句。goto语句的形式为:goto 标识符;

  • goto易于造成程序混乱,代码难以阅读,并且其他跳转语句、return和exit语句能够满足大多数需要goto语句的情况。除非万不得已,尽量不要使用。

例:

#include <stdio.h>int main()
{int i = 0;while (i < 10){switch(i){case 0:case 1:case 2:case 3:printf("%d 小于 4\n", i);break;default:goto bigThan4;}i++;}bigThan4: printf("i开始不小于4\n");return 0;
}

第五章 函数与程序结构

函数的声明与定义

函数的声明

  • 在C语言中函数的定义顺序是有讲究的:默认情况下,只有后面定义的函数才能调用前面定义过的函数。
  • 如果想把函数定义写在main后面,而且main函数能够正常使用这些函数,那么就必须在main函数前面进行函数的声明。
    例:
  // 只是做个函数声明,并不用实现int sum(int a, int b);int main(){int c = sum(1, 4);return 0;}// 函数的定义(实现)int sum(int a, int b) {return a + b;}
  • 函数的声明格式
    1> 格式

返回值类型 函数名 (参数1, 参数2, …)

只要你在main函数前面声明过一个函数,main函数就知道这个函数的存在,就可以调用这个函数。而且只要知道函数名、函数的返回值、函数接收多少个参数、每个参数是什么类型的,就能够调用这个函数了,因此,声明函数的时候可以省略参数名称。比如上面的sum函数声明可以写成这样:

int sum(int, int);

究竟这个函数是做什么用的,还要看函数的定义。

2> 如果只有函数的声明,而没有函数的定义,那么程序将会在链接时出错

多源文件开发

  • 为什么要有多源文件

1> 在编写第一个c语言程序的时候已经提到:我们编写的所有C语言代码都保存在拓展名为.c的源文件中,编写完毕后就进行编译、链接,最后运行程序。

2> 在前面的学习过程中,由于代码比较少,因此所有的代码都保存在一个.c源文件中。但是,在实际开发过程中,项目做大了,源代码肯定非常多,很容易就上万行代码了,甚至上十万、百万都有可能。这个时候如果把所有的代码都写到一个.c源文件中,那么这个文件将会非常庞大,也非常恶心,你可以想象一下,一个文件有十几万行文字,不要说调试程序了,连阅读代码都非常困难。

3> 而且,公司里面都是以团队开发为主,如果多个开发人员同时修改一个源文件,那就会带来很多麻烦的问题,比如张三修改的代码很有可能会抹掉李四之前添加的代码。

4> 因此,为了模块化开发,一般会将不同的功能写到不同的.c源文件中,这样的话,每个开发人员都负责修改不同的源文件,达到分工合作的目的,能够大大提高开发效率。也就是说,一个正常的C语言项目是由多个.c源文件构成。

#include

  • #include的作用
  1. #include 是C语言的预处理指令之一,所谓预处理,就是在编译之前做的处理,预处理指令一般以 # 开头
  2. #include 指令后面会跟着一个文件名,预处理器发现 #include 指令后,就会根据文件名去查找文件,并把这个文件的内容包含到当前文件中。被包含文件中的文本将替换源文件中的 #include 指令,就像你把被包含文件中的全部内容拷贝到这个 #include 指令所在的位置一样。所以第一行指令的作用是将stdio.h文件里面的所有内容拷贝到第一行中。
  3. 如果被包含的文件拓展名为.h,我们称之为"头文件"(Header File),头文件可以用来声明函数,要想使用这些函数,就必须先用 #include 指令包含函数所在的头文件
    #include 指令不仅仅限于.h头文件,可以包含任何编译器能识别的C/C++代码文件,包括.c、.hpp、.cpp等,甚至.txt、.abc等等都可以
  • #include <>和#include ""的区别

二者的区别在于:当被include的文件路径不是绝对路径的时候,有不同的搜索顺序。

  1. 对于使用双引号""来include文件,搜索的时候按以下顺序:

    • 先在这条include指令的父文件所在文件夹内搜索,所谓的父文件,就是这条include指令所在的文件
    • 如果上一步找不到,则在父文件的父文件所在文件夹内搜索;
    • 如果上一步找不到,则在编译器设置的include路径内搜索;
    • 如果上一步找不到,则在系统的INCLUDE环境变量内搜索
  2. 对于使用尖括号<>来include文件,搜索的时候按以下顺序:
    • 在编译器设置的include路径内搜索;
    • 如果上一步找不到,则在系统的INCLUDE环境变量内搜索

头文件.h和源文件.c的分工

  • 跟printf函数一样,我们在开发中会经常将函数的声明和定义写在不同的文件中,函数声明放在.h头文件中,函数定义放在.c源文件中。
  • 运行步骤分析
  1. 在编译之前,预编译器会将sum.h文件中的内容拷贝到main.c中

  2. 接着编译main.c和sum.c两个源文件,生成目标文件main.o和sum.o,这2个文件是不能被单独执行的,原因很简单:

  • sum.o中不存在main函数,肯定不可以被执行

  • main.o中虽然有main函数,但是它在main函数中调用了一个sum函数,而sum函数的定义却存在于sum.o中,因此main.o依赖于sum.o

  1. 把main.o、sum.o链接在一起,生成可执行文件

  2. 运行程序

函数的参数

实参和形参

  • 形参出现在被调函数当中,在整个函数体你都可以使用。形参定义时编译系统不分配储存空间,只有在调用该函数时才分配内存单元。调用结束内存单元被释放,故形参只有在函数调用时才有效,调用结束后不能再使用。
  • 实参出现在主调函数当中,当函数调用时,主调函数把形参的值传送给被调函数的形参,从而实现函数间的数据传递。传递方式有两种:值传递和地址传递方式。

参数总结

  • 数组元素(下标变量)作为函数的参数进行的数据传递是值传递方式,数组名(数组首地址)、数组元素的地址(&arr[0])作为函数参数进行的数据传递是地址传递方式。
  • 实参为数组名时,形参接收时可以有三种形式:带下标的数组名(arr[0])。不带下标的数组名(arr)、可接收地址值的指针变量名(*a)。由于是参数组和形参数组都指向同一段内存单元,故它们操作的是同一批数据,所以形参的改变就是改变了实参中的数据。

函数的调用

  • 一般来说,执行源程序就是执行main主函数,其他函数只能被主函数调用,而其他函数之间也可以互相调用。

标准库函数

  • 分为:I/O函数,字符串,字符处理函数,数学函数,接口函数,时间转换和操作函数,动态地址分配函数,目录函数,过程控制函数,字符屏幕和图形功能函数。

    这些库函数在不同的头文件中声明。比如:

    • math.h头文件中有:sin(x),cos(x),exp(x)(求e^x),fabs(x)(求x的绝对值)等库函数。

    • stdio.h头文件中有:scanf(),printf(),gets(),puts(),getchar(),putchar()等库函数。

    • string.h头文件中有:strcmp(),strcpy(),strcat(),strlen等库函数。

函数的定义

(1)定义无参函数

类型名 函数名()

{
函数体
}

or

类型名 函数名(void)

{
函数体
}

(2)定义有参函数

类型名 函数名(形式参数表列)

{
函数体
}

(3)定义空函数

类型名 函数名()

{ }

调用

函数调用时的参数传递

  • 函数间通过参数来传递数据,即通过主调函数中的实际参数(实参)向被调用函数中的形式参数(形参)进行传递。

  • 实参向形参传递数据的方式:实参将值单向传递给形参,形参的变化不影响实参值。形参交换了数据,而实参保持原数据不变。这是单向的值传递,所以形参的值改变后而实参的值没有改变。

    • 形参在函数中是变量名,在函数调用时,形参被临时分配相应的内存,调用结束后,形参单元被释放,而实参单元保留并维持原值。
    • 实参是表达式,负责向对应的形参标识的内存单元传递数据,实参向形参的数据传递是“值传递”。
    • 实参与形参必须个数相同
    • 对应的形参和实参的类型必须一致

函数的返回值

  • 函数的返回值通过函数中的return语句获得。如果需要从调用函数带回一个函数值(供主函数使用),被调函数中需包含return语句。
  • 在定义函数时要指定函数值的类型

int max(float x,float y) //函数值为整型
char letter(char c1,char c2) //函数值为字符型
double max(int x,int y) //函数值为双精度型

  • 函数类型决定返回值的类型。

函数的嵌套

  • 定义一个函数时不能定义另外一个函数,但是可以调用
  • 例:使用嵌套找出四个数中的最大值
#include<stdio.h>
#include<stdlib.h>
int max2(int a, int b)          //找出a和b中的最大值
{if (a >= b){return a;          //  a作为返回值}return b;                //  b作为返回值
}
int max4(int a, int b, int c, int d)    //定义找4个数最大值的函数
{int m;     //存最大值m = max2(a, b);      //调用max2函数,将a,b中大的值放在m中m = max2(m, c);      //调用max2函数,将a,b,c中大的值放在m中m = max2(m, d);     //调用max2函数,将a,b,c,d中大的值放在m中return m;     //返回到主函数
}
int main()
{int a, b, c, d;int max;printf("请输入四个数:\n");scanf("%d%d%d%d", &a, &b, &c, &d);max = max4(a, b, c, d);           //调用max4函数printf("最大数位:%d\n", max);system("pause");return 0;
}

函数的递归

函数递归的定义和优缺点

  • 程序调用自身的行为就是递归。可以直接或间接的调用,本质是把复杂的问题转化为一个规模小的问题。递归一般只需少量的代码就可描绘出多次重复计算。其主要思考方式在于大事化小

  • 优点是为具有某些特征的编程问题提供了最简单的策略,缺点是层层调用,算法的复杂度可能过高,以致于快速耗干了计算机的内存资源,不方便阅读和维护等。

  • 例如: 用递归求阶乘

int fac(int n)//非递归
{int ret = 1;for (int i = 1; i <= n; i++){ret *= i;}return ret;
}
int fac(int n)//递归
{if (n > 0)return n * fac2(n - 1);elsereturn 1;
}
int main()
{int n = 0;scanf("%d", &n);  printf("%d\n", fac(n));return 0;
}

局部变量和全局变量

  • 讨论局部变量和全局变量其实就是在讨论作用域

局部变量

  • 首先是一个变量,其次,这个变量只是在程序的局部范围内有效

  • 局部变量定义在哪些位置:

    1. 函数的开头;
    2. 函数内的复合语句内定义;
    3. 形式参数;
    4. 函数中间(非开头);
  • 注意:
    1)程序执行到某个函数时,这个函数内部的局部变量将会被分配内存空间;局部变量在函数执行结束后,变量所占内存将会被释放;

全局变量

  • 可以在全局范围内有意义的变量;所谓全局也并不是真正的全局,而是在定义处以下的范围内才是有效的;
  • 全局变量定义的位置:
    1. 文件开头;
    2. 函数前;
    3. 函数后;
    4. 文件结尾;
#include <stdio.h>char Global_1 = 'A';  //源文件开头:在此行以下的所有定义的函数都有效;
void main()
{}char Global_2='B';  //函数后和函数前:此全局变量在此行之前是无效,只能在此之下的函数中有效;void fun1()
{char Local_1 = 'a';{char local_2 = 'b';}char Local_3 = 'c';
}char Global_3 = 'B';//程序结尾:程序结尾的全局变量是没有意义的;
  • 注意
    1)为了区别全局变量和局部变量,往往大家在写程序的时候都喜欢将全局变量的首字母大写,而局部变量的首字母小写;
    2)全局变量的优点和缺点:
    优点:C语言的函数,每次最多只能返回一个值,但是如果定义了全局变量,那么在这个变量的有效范围内,很多函数都能改变这个变量的值,所以增加了函数之间的联系,通过函数的调用可以得到一个或一个以上的值;
    缺点:(大量使用全局变量的情况下)
    1)占内存:全局变量所占的内存空间不会像局部变量一样会被释放;
    2)降低程序清晰性:无法随时确定定义的全局变量的值的大小;
    3)降低通用性:程序设计时要求函数的“内聚性”强,函数与函数之间“耦合性”弱;定义全局变是一定要注意在有效范围内变量不能重名,并且当全局变量被跨文件调用的函数调用时,不能出现全局变量与所跨文件中存在重名变量,否则有可能会出错;所以,为了提高程序的可靠性,可移植性和可读性等,全局变量尽量少用;

头文件

  • include的作用:简单一句话:在include的地方,把头文件里的内容原封不动的复制到引用该头文件的地方。

  • 头文件的引用
    头文件引用有两种形式:#include < stdio.h> 和 include "main.h “。
    用< >引用的一般是编译器提供的头文件,编译时会在指定的目录中去查找头文件。具体是哪个目录,编译器知道,我们不用关心。用” “引用的一般是自己写的头文件,编译时,编译器会在项目所在的文件夹中进行查找,如果还才存在子文件夹,则在Makefile中用-I(大写i)来指定头文件搜索目录。
    总结系统提供的头文件用< >引用, 自己写的用” "引用。

  • 头文件的内容
    头文件里一般包括宏定义, 全局变量, 函数原型声明

  • 头文件的格式

#ifndef 头文件名 //头文件名的格式为"头文件名",注意要大写
#define 头文件名
头文件内容

#endif

例:

#ifndef _MAIN_H_    //如果没有定义头文件main.h,则执行下面的代码。这是防止重复定义
#define _MAIN_H_    //定义头文件//下面的代码是头文件的内容
#include<stdio.h>//头文件
#define ADD 1 //宏定义
extern int x; //全局变量
void swap(int a, int b);//函数声明#endif    //表示头文件结束

内部函数和外部函数

  • 函数的调用,一般是对同一个源文件中的其他函数进行调用的,也可以对另外一个源文件中的函数进行调用
    C语言中,根据函数能否被其他源文件调用,分为内部函数和外部函数
    外部函数,可以被其他源文件调用的函数
    内部函数,只在定义的文件中有效

第六章 数组

一维数组的创建和初始化

  • 数组的创建

数组是一组相同类型元素的集合。

数组的创建方式:

type_t   arr_name[const_n];
//type_t 是指数组的元素类型
//const_n 是一个常量表达式,用来指定数组的大小

实例:

//代码1
int arr1[10];
//代码2
int count = 10;
int arr2[count];
//数组时候可以正常创建?不能。
//代码3
char arr3[10];
float arr4[1];
double arr5[20];
  • 注意:数组创建过程中,[]中必须是常量而不能是变量。

  • 数组的初始化

数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。

  • 一维数组的使用

对于数组的使用我们之前介绍了一个操作符:[],下标引用操作符。它其实就数组访问的操作符。

#include <stdio.h>
int main(){    int arr[10] = {0};//数组的不完全初始化   //计算数组的元素个数    int sz = sizeof(arr)/sizeof(arr[0]);  //对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以:    int i = 0;for(i=0; i<10; ++i)    {printf("%d ", arr[i]);   }    return 0;
}

总结:

1.数组是使用下标来访问的,下标是从0开始。
2.数组的大小可以通过计算得到。
  • 一维数组在内存中的储存
#include <stdio.h>
int main() {int arr[10] = { 0 };int i = 0;for (i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i) {printf("&arr[%d] = %p\n", i, &arr[i]);}return 0;
}

输出结果:

仔细观察输出的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增。
由此可以得出结论:数组在内存中是连续存放的。

二维数组的创建和初始化

  • 二维数组的创建
//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];
  • 二维数组的初始化
//数组初始化
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};
  • 二维数组的使用
#include <stdio.h>
int main(){   int arr[3][4] = {0};   int i = 0;   for(i=0; i<3; i++)    {int j = 0;for(j=0; j<4; j++)        {arr[i][j] = i*4+j;      }  }    for(i=0; i<3; i++)    {int j = 0;for(j=0; j<4; j++)        {printf("%d ", arr[i][j]);     }   }    return 0;
}
  • **二维数组在内存中的存储 **
#include <stdio.h>
int main(){   int arr[3][4];  int i = 0;    for(i=0; i<3; i++)    {int j = 0; for (j = 0; j < 4; j++) { printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);}}   return 0;
}

输出结果:

数组越界

  • 数组的下标是有范围限制的。
  • 数组的下规定是从0开始的,如果输入有n个元素,最后一个元素的下标就是n-1。
    所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
  • C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,所以程序员写代码时,最好自己做越界的检查。

关于数组名的解释

  • 数组名是数组首元素的地址。(两个例外)

  • sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组。

  • &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。

  • 除此1,2两种情况之外,所有的数组名都表示数组首元素的地址。

关于数组下标的解释

  • 为什么数组下标要从0开始编号?

为什么数组下标要从0开始编号,而不是从1开始呢?从1开始不是更符合人类的思维习惯吗?
从数组存储的内存模型上来看,下标实际上指的是偏移量(offset)。例如:一个整型数组 int arr[LEN],

  • 从0开始编号,元素arr[i]的寻址计算公式是:address(arr[i]) = address(arr) + i * sizeof(int)。
  • 从1开始编号,元素arr[i]的寻址计算公式是:address(arr[i]) = address(arr) + (i - 1) * sizeof(int)。

对比两个公式,从1开始编号会多一次减法运算,对应到CPU就会多一条减法指令。而数组取下标是一个高频操作,故从0开始效率更高。另外,C语言的设计者从0开始编号数组元素,之后的C++、Java、Python等高级语言也沿用了C的编号习惯,这也在一定程度上降低了C语言程序员学习其他编程语言的成本。当然,并不是所有语言的数组都是从0开始编号,比如MATLAB。

第七章 指针

指针和地址

  • 同C语言中其他变量一样,把指针也看成是一种变量即可,这种变量专门存储地址值。
int a = 100;
int* b = &a;

a是一个整形变量,值为100;b是一个指针变量,值是变量a的地址。
变量和指针的类型必须相同。

交换a和b的值:

void swap(int x, int y)
{int tmp = x;x = y;y = tmp;
}
void change()
{int a = 100;int b = 200;swap(a, b);
}//err

结果a,b的值并没有交换成功。
原因是:C程序在调用函数时使用“按值调用”,这意味着变量的值直接从调用函数复制到被调函数的实参中,“按值调用”是C语言中调用函数的唯一方式。
改写:

void swap(int* x, int* y)
{int tmp = *x;*x = *y;*y = tmp;
}
void change()
{int a = 100;int b = 200;swap(&a, &b);
}

一个函数只能访问自己的栈帧。
但是,通过指针,一个函数可以间接地读写另一个栈帧中的变量值。

一篇文章畅游在C语言基础知识学习的海洋中(持续更新中……)相关推荐

  1. R语言 plot swimmer_R语言基础知识学习(四):R中的画图函数--plot()函数

    plot()函数是R中基本的画x-y两个变量的函数,其用法如下为:plot(x, y, ...) 例如:首先我用runif()函数产生了两列随机数:x1,y1,然后用plot()函数直接画图: > ...

  2. python基础知识-一篇文章搞定Python全部基础知识

    原标题:一篇文章搞定Python全部基础知识 前言: 1.Python软件安装 第一章.字符串及数字变量 1.变量 要点提炼:Python变量为强类型动态类型.换言之,变量很任性,你给他int,他就是 ...

  3. 数据库SQL语言学习--数据查询(持续更新中)

    数据库SQL语言学习--数据查询(持续更新中) 上机练习1 1.              启动SQL Server 2008中的 SQL Server Management Studio. 2.   ...

  4. 【五】 C语言基础知识学习回顾 | 一篇搞定C语言基础 | 内附详细代码以及注释

    一 .C语言学习第一天 1.1 编写C语言代码:hello.c #include<stdio.h> #include<stdlib.h> //调用system系统函数需要包含的 ...

  5. R语言基础知识-学习笔记汇总

    B站课程:生信必备技巧之R语言基础教程全集的代码笔记 1.R语言包安装 rm(list = ls()) # 设置镜像: options()$repos options()$BioC_mirror #o ...

  6. 前端面试知识自己的一些整理 ---持续更新中

    - title: 自己整理的面试复习资料 date: 2019-03-20 12:27:51 tags: 面试 前端 CSS3+H5 [CSS3.0 帮助文档.chm](CSS3.0 帮助文档.chm ...

  7. 一篇文章搞定Python全部基础知识

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 前言: 1.Python软件安装 第一章.字符串及数字变量 1.变量 要点提炼:Python变量为强类型动态类型.换言之 ...

  8. 关于python论文2000字_一篇文章搞定Python全部基础知识

    前言: 1.Python软件安装 第一章.字符串及数字变量 1.变量 2.数字型数据 要点提炼:这下面那张图就行,至于其它的,就是文本转字数(int),数字转文本(Str) 3.字符串 要点提炼:字符 ...

  9. C#基础知识学习(2)string类中的方法

    1.Compare 比较字符串 用来比较2个字符串的长度大小和值是否相同,相同则返回0,当x比y小返回-1,否则返回1,如果长度相同,且值不同,则返回1,代码如下 public static void ...

最新文章

  1. JavaSE_NIO_ByteBuffer
  2. OPPORTUNITIES_GET_ENTITY not implemented in data provider class
  3. 判断用户的参数(条件测试语句)
  4. java settime_Java日历setTime()方法及示例
  5. android.hardware.Camera类及其标准接口介绍
  6. Python爬虫有什么用,网友纷纷给出自己的答案,爬虫能做的还是很多的
  7. JQuery --- 第三期 (jQuery事件相关)
  8. iOS开发UI篇—APP主流UI框架结构
  9. 自学python能找到工作吗-通过自学python能找到工作吗
  10. html5 苹果手机上传word文件_DocumentsbyReaddle文件管理器,让你的苹果手机 更顺畅...
  11. Cisco防火墙概述和产品线
  12. 什么是七模全网通DTU 全网通DTU特色功能
  13. (三)feild ii 相控阵聚焦成像:RF信号到成像全过程
  14. 在官网上下载慢解决办法
  15. 怀念王选,怀念北大计算机研究所
  16. 迈阿密牛津计算机专业,迈阿密大学牛津分校计算机科学
  17. QAxObject 读写 excel
  18. Linux下如何创建和取消软连接
  19. dockers 拷贝
  20. 【Windows8开发】关于WinRT组件,WinRT dll,Win32 dll,WinRT exe组件的一些尝试

热门文章

  1. ICDM‘20 AANE: Anomaly Aware Network Embedding For Anomalous Link Detection论文笔记
  2. 京东校招java笔试题_京东2018校招技术笔试编程题汇总
  3. 计算机图形学——多边形裁剪(待改良可运行)
  4. 云存储——Hotfile
  5. 游戏中常用的设计模式总结
  6. Win11系统安装NET3.5失败解决方案
  7. 火山视窗超级编辑框彩色文本演示
  8. 2020年国内最新最优目标检测(完结篇)提供下载链接
  9. 达内 JAVA UI设计 网络营销 嵌入式 正版高清全套视频
  10. 杰理之FLASH-OTP区域使用方法【篇】