C语言谭浩强版本学习笔记(1)

C语言谭浩强版本学习笔记(1)
77-15号C语言学习笔记-------------------------------------------------
C语言是基于过程的语言。
C语言只包含37个关键字
C语言是一个很小的内核语言
C的编译系统十分简洁
C语言包含34种运算符
可以使用指针实现复杂数据结构的运算
C语言是完全模块化和结构化的语言
C语言中对数组下标越界不检查自行检查
C语言可以进行位操作,直接访问物理地址,可以直接操控硬件
C的可移植性好
C的主要用途之一就是编写嵌入式程序

include文件中的.h表示的是headfile文件,
同时其中的stadio是standard input & output的缩写

如果不使用上述的头文件那么将会使得printf语句无法执行
在程序运行的时候编写的//注释会编译成一个空格不执行

C中只有两种注释:
1.//表示的是单行注释
2./**/ 是块式注释
在字符串中使用上述的注释表示字符串的内容

在输出中printf(“sum is %d’\n”,sum)
在运行的时候sum将替换%d(表示十进制)

在使用自定义的函数时我们要么就是将自定义函数放在main函数之前
要么就是在main函数中先声明一下自定义函数即可

c语言中使用&表示的是地址符
&a表示的是变量a的地址

7-15号晚上学习笔记:------------------------------------------------
一个原程序文件中包含的有:
预处理指令(该指令在编译之前先由预处理器进行预处理,就是将头文件中包含的代码
添加到使用本头文件的源文件中然后组成一个完整的可编译的文件进行编译)
全局声明(在函数之外的数据声明)
函数定义

函数是C程序的重要组成部分
一个C程序中必须包含一个main函数(并且只能有一个)
对于大型的程序需要的是使用多个源程序文件(一个源程序文件就是一个程序模块)
不同编译系统提供的库函数是不同的

一个函数包括两个部分:
函数首部(如果一个函数没有返回值那么可以在函数名称后边的括号中使用void也可以是空括号)
函数体(最外层的一对花括号是函数体的范围)
函数体一般包含的是两个部分:声明部分和执行部分
一个空函数是合法的(空函数就是指不包含两部分的函数)
程序总是从main函数开始执行并不在乎main函数在程序中的位置

C语言本身不提供输入输出语句
程序中应当包含注释增强可读性

源程序文件在编译之后生成的二进制文件后缀名是:.obj(该文件就是目标程序)
多个源文件编译之后生成的多个目标文件需要装配起来并与函数库相连接成一个整体
生成一个可以使计算机执行的目标程序(叫做可执行程序,其后缀名是.exe)

即使只有一个源程序文件那么在编译之后也不可以直接运行而是还要和函数库进行连接
才可以执行

目前多数的编译系统都是直接在集成开发环境(IDE)中

程序设计是指:
从确定任务到得到结果、写出文档的全过程

从确定问题到解决问题需要以下几个阶段:
问题分析(建模)
设计算法(一般用流程图来表示解题的步骤)

测试必须要进行

编写程序文档是很有必要的

软件是计算机程序和程序文档的总称

7-16号C语言学习笔记(第二章)-------------------------------------
一个程序的两部分:
对数据的描述(数据结构)
对操作的描述(算法)
算法+数据结构 = 程序

算法 数据结构 程序设计方法 程序设计语言工具 是程序员必备的技能
广义的说为解决一个问题而采取的方法和步骤就是算法
计算机算法分为两种:
数值运算算法(求值求解)和非数值运算算法(主要是在事务管理方面运用)

算法的特性:
有穷性(事实上有穷性往往控制在合理的范围之内)
确定性(算法的含义应当是唯一的)
有零个和多个输入
有一个或多个输出(没有输出的算法是没有意义的)

常用的表示算法的方法:
自然语言
传统流程图(菱形框是对一个给定条件的判断;连接点表示的是将画在不同地方的流程连接起来;
注释框只是用来对某些框中的操作做出一些必要的补充说明)
结构化流程图
伪代码

从流程图上很容易发现算法的错误
一个流程图包括以下几个部分:
1.表示相应操作的框
2.带箭头的流程线
3.框内外必要的文字说明

在结构化方法推行之后大多数采用的是N-S结构化流程图代替这种传统的流程图

如同乱麻一样的算法被称作BS型算法,使得算法可靠性和可维护性难以保证

为了提高算法的质量必须限制箭头的滥用

三种基本结构:
顺序结构
选择结构(其中的AB两个处理框其中之一可以是空的)
循环结构(当型循环结构和直到型循环结构)

上述三种基本结构共同的特点是:
只有一个入口
只有一个出口
结构内的每一个部分都有机会被执行到
结构内不存在“死循环”(无终止的循环)

以上三种基本结构可以解决任何复杂的问题

由基本结构(或者是从基本结构派生出来的结构)所构成的算法是结构化算法

用N-S结构化流程图表示的算法都是结构化算法
如果一个算法不可以分解成若干个基本结构那么它必然不是一个结构化算法
N-S又称为盒图

用伪代码表示算法
流程图适合表示一个算法但是在设计算法的时候并不理想
使用伪代码并没有固定格式、没有严格的语法规则
可以用英文,也可以用中英文混用
软件专业一般使用伪代码
用计算机语言表示的算法是计算机能够执行的算法
写出程序只是描述了算法只有运行了程序才是实现了算法

2.6结构化的程序查询方法
结构化程序的设计思路:把一个复杂的问题的求解过程分阶段进行,每个阶段处理的问题都控制在人们容易理解和处理的范围内
得到结构化程序的方法:
1.自顶向下
2.逐步细化
3.模块化设计
4.结构化编码

提倡使用自顶向下,逐步细化的方法进行程序设计
对程序模块的划分是使用的自顶向下的思路设计的
程序中的子模块通常是函数(一般不超过50行)
划分子模块的时候应当注意子模块的独立性(耦合性越小越好)

7-17号下午C语言学习----------------------------------------------
顺序程序设计举例
将双精度数字转换为float类型的时候会损失精度
数据的表现形式及其运算
常量和变量
常量
整型常量
实型常量
十进制小数形式
指数形式(注意:E和e之前必须要有数字,并且e和E都后面必须为整数)
字符常量(采用的是ASCII码存储在计算机中的)
普通字例如使用’号的一个字符;注意:单撇号’只是界限符,字符常量只能是一个字符)
转义字符(常用的:\f 表示换页;\n表示换行;\r表示回车也就是将光标位置移动到本行的开头;\oxx表示一个八进制的数字;
\x h[h…]其中h表示的是一个十六进制的数字;其中:\033或\X1B 都表示ESC控制符;\0或\000 都是表示的空操作字符,常用在字符串中)
字符串常量
符号常量
格式:使用#define PI 3.1415926 (在程序编译的过程中编译器先处理该常量实现)
使用符号常量的好处:
1.含义清楚
2.在需要改变程序中多处使用该常量的时候可以做到“一改全改”
注意:符号常量不占内存
变量
注意:变量必须先定义后使用(定义变量时候C99允许在函数中的复核语句中定义变量)
变量名实际上是一个名字代表的一个存储地址
常变量
C99允许使用常变量,使用const定义(注意:在变量存在期间其值不可改变)
可以说常量是没有名字的不变量;同时使用常变量之后可以不必使用符号常量
标识符
简单地说标识符就是一个对象的名字
C语言中规定:标识符只可以是:数字 字母 下划线
并且,只可以字母或下划线开头
一般来说变量名使用小写字母表示
注意:
C语言中规定的是基本字符集中的每一个字符必须使用一个字节存储,空字符也是一个字节,它的所有二进位都是0
对数字0-9的代码,后面一个代码要比前面一个代码大1.

数据类型
用计算机实现的计算不是抽象的,故会有一定误差
数据类型就是对数据分配存储单元的安排,包括存储单元的长度(占多少字节)以及数据
的存储形式
指针类型是C99新增加的
枚举类型是用户定义的整数类型
数组类型和结构体类型统称为组合类型
VisualC++中为char类型分配一个字节,为int类型分四个字节

整型数据
整型数据的分类
基本整型(int)(其中的范围是:2^15 - 1 = 32767;最小值是-2^15 = -32768)
短整型(short int)在Visual中是短整型占2个字节
长整型(long int) 在Visual中长整型占比4个字节
双长整型(long long int)这个是C99中新增加的类型
C标准中没有特别说明各数据类型的存储长度只是需要short < int < long < long long 即可
不同类型系统中需要注意改变数据类型
对于某些实际应用场景中,可以使用unsigned加在类型符号的前边表示无符号整数类型
但是默认是有符号类型的
只有整型数据可以加signed 和 unsigned,实型不可以加
对无符号十进制数据使用%u格式输出,但是对有符号数十进制使用%d进行输出
C99中将字符型的数据也作为整数类型

字符和字符代码
不能显示的字符包括:空null 警告(以\a表示) 退格以\b表示 回车以\r表示回车也就是将光标位置移动到本行的开头;\oxx表示一个八进制的数字;
C语言中指定用一个字节表示一个字符(不区分系统)此时字节中的第一个位是0
字符’1’ 和 整数1 不是一样的

字符变量
字符变量用类型符char定义
解释代码:
char test = ‘?’ 字符’?'的ASCII码是63,那么表示将63赋值给test变量
可以将0-127的整数赋值给char变量
使用%d输出十进制;使用%c输出字符

浮点型数据是用来表示具有小数点的实数的
C语言中实数是以指数形式存放到存储单元中
由于小数点位置浮动所以实数的指数形式成为浮点数
float类型
系统为float分配四个字节
在存储时系统将实数的指数部分和小数部分分别存放
小数部分的小数部分前面的数为0
小数部分占的位数越多那么数字的精度就越大;指数部分占的位数越多那么数字表示的范围越大
float类型的范围是:-3.4 * 10 ^ (-38) — 3.4 * 10 ^ 38

double类型
系统double类型分配八个字节,可以得到15位有效数字,同时数值范围是:-1.7 * 10 ^ -308 —1.7 * 10 ^ 308
在C语言中进行运算的时候都将float转换为double类型以提高计算精度

long double类型
Turbo C对long double型分配16个字节
但是在Visual C++中为其分配的是8个字节
在一个整型中后边使用L或者l都可以表示长整型
在Visual C++中由于int和long int都是使用的四个字节存储的那么没有必要使用long int 型的
C编译系统把浮点型常量都按双精度处理,分配八个字节
可以在常量的末尾加上字符(例如:l f 等)实现强制转换

C中除了控制语句和输入输出以外几乎所有的基本操作都作为了运算符处理
多数的C编译系统会使用向0取整的方法

7-18号C语言学习笔记------------------------------------------------
两个实数相除的结果是双精度实数,两个整数相除的结果是整数
在中文操作系统ASCII码在127之后的部分被作为中文字符处理
%运算符要求参加运算的是整数(结果也是整数),除此之外其他任何运算符的操作数
都可以是任何算术类型
建议将++ 和 – 作为单独的表达式使用
算术运算符的结合方向都是自左向右
结合性的概念在一些其他高级语言中是没有的。这个是C语言的特点之一
如果运算符左右两边的数据类型不同那么先转换为同一种类型然后在进行运算
同一个字母其小写字母比大写字母的ASCII码大32
在进行强制类型转换的时候原来的值都没有发生变化,只是产生了一个临时值
的那个临时值进行赋值之后就不存在了
强制类型转换优先于%运算符

C语句
3.4.1C语句的作用和分类
一个函数包含声明部分和执行部分
goto语句基本上在结构化程序中不使用
任何表达式加分号都是一个语句
函数调用语句也属于表达式
复合语句常用在if语句或循环语句中

最基本的语句—赋值语句
最常用的语句是:赋值语句和输入输出语句
在安排输出的时候常用"\t"调整输出的位置
凡是二元运算符都可以与赋值语句一起组合成复合赋值符
由赋值运算符将一个变量和一个表达式连接起来的式子称为“赋值表达式”
对赋值运算符的右边的表达式进行运算后,赋值符号左右两边的值都是该值
赋值运算符的左边的数据称为“左值”,有存储空间并可以被赋值的数据可以作为“左值”
“左值”都可以作为右值
赋值运算符按照自右向左的顺序结合

赋值运算中的类型转换
将浮点型数据转换为整型时,先对浮点数取整,即舍弃小数部分,然后赋予整型变量
将整型数据赋值给单双精度变量时,数值不变,但是以浮点数形式存储到变量中
将一个双精度(double)数据赋值给float时,先将double数转换为单精度的float,
即只取double型数据的有效数字的6-7位
对int型数据转换为short型的只需将int类型的低位数对应到short中即可(会发生截断)
赋值语句属于表达式语句

int a,b,c = 5;(表示只对c赋值5)
一般变量的初始化不是在编译阶段完成的(只有静态存储变量和外部变量的初始化是在编译阶段完成的)

数据的输入和输出
使用%lf格式声明表示输入的是双精度型实数

7-18号C语言学习笔记-------------------------------------------------
使用7.2表示的就是输出的时候结果占7列其中小数点之后的数字占2列(此时对于第三列按照四舍五入处理)
输出时使用%7.2f的作用是不管整数部分是不是对齐的,但是小数部分是对齐的(从右向左输出)
C语言本身不提供输出语句
实际上printf 和 scanf不是C语言提供的,只是在编写函数的时候命名为了这样
不同的编译系统提供的函数库中:函数的数量、名字、和功能也是不完全相同的
C语言函数库中有:putchar getchar printf scanf puts(输入字符串) gets(输出字符串)
在C的源程序中的头文件中使用 和 使用"stadio.h"都可以实现功能
但是使用前者是标准方式(C的编译系统直接从C函数库中找)
但是后者是先在用户源程序的子目录中找,找不到的话再在C的函数库中找

当用户使用自己编写的文件的时候,可以指定文件的位置(如果不在当前目录下)

详解printf()函数
格式:printf(“格式控制”,“输出表列”)
其中格式控制部分分为两个:一个是格式声明;一个是普通字符
由于printf是函数那么上述的格式声明和普通字符都是其参数
printf(参数1,参数2…参数n) 其中参数1是必须有的

常用的格式字符:
d 表示输出一个十进制的带有符号的整数(可以在格式输出的时候指定数据的域宽(表示所占的列数))
若输出的是Long型–使用%ld输出;若输出的是long long型–使用%lld输出

c格式符–用来输出一个字符
如果整数比较大那么将其的最后一个字节的信息以字符输出

s格式符-- 用来输出一个字符串(输出的时候不包括双引号)

f格式符–用来输出实数(包括单、双精度、长双精度),以小数形式输出
分类:
1.基本型;用%f输出(系统决定的是实数中的整数部分全部输出,小数部分输出6位;最多输出6位小数)
2.指定数据宽度和小数位数(用%m.nf)(注意:不可轻易指定小数部分位数为0)

7-19号C语言学习笔记--------------------------------------------------
使用 %-20.15f 输出表示的是数据靠左输出
e格式符–将实数按照指数形式输出,如果没有指定输出数占的宽度和数字部分的小数位数
很多C编译系统(如Visual C++)会自动给出数字部分的小数位数为6位,指数部分占5列
并且按照标准格式输出:即小数前边非零数字只有一个

当然也可以使用%12.3e输出;表示的是小数部分是3位同时共占12位,靠右输出
其他不常用的格式符:
%i作用和%d一样
%o格式符:表示以八进制整数形式输出(注意:将符号位也按照八进制输出,也就是说将数字在存储空间中的自右向左
每三位一组,实现按照八进制输出)
那么使用o就可以得到存储单元中实际的存储情况

x格式符–作用是以16进制形式输出整数
u格式符–用来输出无符号型数字,以十进制整数形式输出
g格式符–系统选择使用f格式或e格式输出,选择其中长度较短的格式不输出无意义的0

c表示以字符形式输出只输出一个字符

附加字符:
l表示长整型整数
m表示数据的最小宽度
n表示如果是实数那么表示输出n位小数,如果是字符串表示截取的字符串个数
-表示输出向左靠齐

7-19号晚上学习C语言------------------------------------------------
用%c输出只考虑一个存储单元中的字节
一个双精度数字只能保证15位有效数字的精确度
float只保证6-7位的有效数字
如果想输出字符“%”那么我们使用两个%%即可输出

scanf实现输出
格式:scanf(格式控制,地址表列)
scanf函数中用到的格式挂附加字符:
l–输入长整型数据
h–输入短整型数据
域宽–指定输入数据所占宽度(列数),域宽应为正整数

需要注意的问题
1.格式控制后面的部分应该是变量地址而不是变量名
2.如果在格式输出的时候除了格式声明之外还有其他字符,则在输入数据时在对应的位置上应输入与这些字符相同的字符
例如:应该使用的是scanf(“a=%f,c=%f,b=%f”,&a,&b,&c) 那么我们在输入的时候需要输入的是:a = 1,需要加逗号
3.在使用scanf("%c%c%c",&c1,&c2,&c3)的时候我们需要直接连续输入三个字符不可以带空格或者是逗号
(也就是说在使用%c实现输入的时候我们只需要连续输入字符即可)
4.在输入字符的时候如输入如空格、回车、Tab键或遇到非法字符时(不属于数值的字符)
认为该数据结束
例如:scanf("%d%c%f",&a,&b,&c); 在输入的时候如果输入的是123a1232o.23 其中当系统检查到o的时候会认为是非法字符则数据结束

字符输入输出函数
1.调用purchar函数输出一个字符
putchar©
只可以输出字符但是不可以输出整数
2.使用gerchar()函数只可以得到一个字符想要得到多个字符我们使用多个该函数
需要注意的是使用enter是换行符也占用了一个字符
同时注意的是执行getchar()函数不仅可以从输入设备获得一个可显示的字符而且可以获得屏幕上无法显示的字符(如控制字符)

重点:======//测试使用getchat()函数作为putchar()函数中参数的代码(可以连续输入)
putchar(getchar());
putchar(getchar());
putchar(getchar());
putchar(’\n’);

也可以在printf("%c",getchar()); 实现直接将输入的字符输出。

需要注意的是使用pow()函数可以求y ^ x的结果

Visual中对字符的存储是作为signed char类型存储的,存字符的有效范围是0-127
在使用scanf的时候需要注意回车符可能作为一个字符读入

若连续使用两个getchar函数输出字符时a和b之间没有空格连续输入

第四章—选择结构程序设计(7-20号学习C语言笔记)------------------------------------------
1.使用if实现两个分支结构
2.使用switch实现多个分支结构

if语句的一般形式:
if(表达式) 语句1
[else 语句2]
if语句中表法式可以是关系表达式、逻辑表达式还可以是数值表达式
关系表达式就是两个数值进行比较的式子
使用if-else语句相当于在else结构中又嵌套一个if

说明:整个if语句也可以写到一行中。例如:if(x > 0) y = 1; else y = -1;
if语句无论写成什么形式,都是一个整体,属于一个语句
else语句是if语句的子句,不可以单独使用
if语句中的判断结果是一个逻辑值(真或假)

关系运算符和关系表达式
关系运算符及其优先次序
其中:
{
<
<=

=
}上述是高优先级的

{

!=
}上述的两个是低优先级别的

赋值运算符 < 关系运算符 < 算术运算符
有以下赋值表达式:d = a>b 表示的是如果是a>b那么就是a>b的值是1;

逻辑运算符中:
使用AND进行表示与;使用OR表示或(在BASIC或Pascal语言中可以使用但是在C中不可以使用)

逻辑表达式:使用逻辑运算符将关系表达式或其他逻辑量连接起来的式子就是逻辑表达式
C中的逻辑运算符:
&&表示的是逻辑与
||表示的是逻辑或
!表示的是逻辑非
其中的&& 和 ||是双目运算符
例如:!a && b || x > y && c(其运算顺序是:先是非!->然后是逻辑与&&->然后是逻辑或||->)

重点:
赋值运算符 < && 和 || < 关系运算符 < 算数运算符 < !(非)
C语言中使用1表示真;使用0表示假
但是在进行判断的时候只要是非零的数值都是真的

例子:
5<6 && 8<3 -!0(计算顺序:先计算<号,然后计算&&号右边的-号,接着计算<号,最后是计算&&即可)

实际上,逻辑运算符的两侧的运算对象还可以是字符型、浮点型、枚举型或者指针型的纯量型数据

在逻辑表达式的求解时,并不是所有的逻辑运算符都被执行,只是在必须执行下一个逻辑运算符才能求出表达式的解时
才执行该运算符。

例如:
int m = 1;
int n = 1;
(m = 3>4) && (n = 1>2)
此时由于m的值是0那么后边的n = 1 > 2不再运算,也就是说后边的n的值还是原来的值1,不是0。

C语言中的条件运算符和条件表达式
max = (a > b) ? a : b;(作用是求最大值)
其中:?是条件运算符。它是C语言中的唯一一个三元运算符
条件运算符的优先级大于赋值运算符
当然上述的条件表达式也可以写成这样的形式:a > b ? (max = a) : (max = b);
也就是说在条件表达式中后边的执行语句也可以是函数表达式 赋值表达式 数值表达式
应当注意的是else语句总是和上边离其最近的if语句进行配对
在使用内嵌的if-else语句时需要尽量将内嵌的if语句写道外层的else语句中,会使程序更加清晰

7-21号C语言学习笔记-----------------------------------------------------------------------------------------
在使用double时候需要使用%lf进行结果的输出
C语言中使用switch中代替由于使用多个if-else嵌套形成比较复杂的语句
有的时候使用switch一次就可以得到结果但是使用if-else时需要至少三层嵌套
需要注意的是在每一个case语句中都有一个break语句(作用是跳转到右花括号处}(也就是程序的最后))
对于当所有的case语句都没有判断成功那么直接执行default中的语句
switch()中值类型一般是整数类型(字符型也可以)
default在swich中最多只有一个
其中的case ‘A’ : 和 default: 语句都是起到标号的作用
各个case标号出现的位置不影响结果
最后一个default中的子句中可以不加break语句
多个case标号可以使用同一个语句 格式如下
case:
case:
case: printf(“得到结果是:%d”); break;
注意当使用fabs()函数时,得到的是一个实数不可以直接和0相比较,应当使用的是判断该值是不是小于一个很小的数
如果是的话就表明该值等于0,那么不等于0

在解决分段函数的问题的时候需要关注的是横纵坐标之间或者是单独有没有某些关系可以使用
建议在使用scanf()函数之前可以使用printf()函数输出提示信息

重点----------
在C的源程序文件中需要注意变量的声明需要在printf()函数和scanf()函数之前不然后出现2096的找不到符号这种诡异错误

第五章循环结构(7-21号晚上C语言学习笔记)

while循环------------------------------
执行后边的循环体(就是复合语句)
while 循环的一般格式:
while(表达式) 语句
循环体只可以是一个语句(但是可以是复合语句)
其中表达式中是循环条件表达式其值是false和true
while循环时先判断表达式的值然后执行循环

do-while循环----------------------------
当花括号中只有一个语句时可以不要
一般形式是:

do
语句
while(表达式)

do-while语句和while语句是完全等价的

for循环---------------------------------
for语句的一般形式:
for(表达式1,表达式2,表达式3){}
其中:
表达式1是 初始条件(可以为0个也可以为多个)
表达式2是 循环条件表达式
表达式3是 作为循环的调整

for循环的执行步骤:
1.求解表达式1。
2.求解表达式2,若为真那么执行循环体,然后执行第三步;若为假,结束循环转到第五步
3.求解表达式3。
4.转回步骤2继续执行
5.循环结束,执行for循环后边的语句

应当注意的是:
1.for循环和do-while循环无条件等价
2.表达式1可以省略但是其中的;不可以省略
3.表达式2也可以省略
4.表达式3也可以省略
5.将三个表达式都省略之后表示的是无限循环

其中表达式1和3可以设置成和循环变量无关的表达式(可以是逗号表达式,其中逗号表达式是按照顺序自左向右进行求解的)
表达式2可以是关系表达式、字符表达式、逻辑表达式、数值表达式(只要是值不是0那么就可以执行)
需要注意的是使用键盘输入的时候是按下Enter之后将输入的内容送到缓冲区,然后在使用的时候需要从缓冲区取得

循环的嵌套------------------------------------
三种循环可以相互嵌套
for循环中可以将循环体中的内容完全放到表达式3中

改变循环执行的状态----------------------------
用break语句提前结束循环
用continue提前结束本次循环(在使用了之后程序跳转到了表达式3处,然后执行之后判断是否继续执行循环)

A span or multiple spans with the predefined event types.

截止到127页循环程序举例

7-22号上午学习笔记+7-23号傍晚C语言学习笔记-------------------------------------------------------------------------------------------------
回顾循环结构:循环结构也叫做重复结构
fabs是求绝对值的函数,并且是双精度数,得到的结果是双精度型
使用abs()函数求整数x的绝对值,结果是整型类型

对于斐波那契数列的改进说明:
由于一个数字n,其的每一对因子,要么是小于根号(n)要么大于根号(n),所以我们只需要判断其中的一部分是否是可以被其因子整除即可
也就是说可以定义一个k其值是:根号(n)的整数部分,从而作为范围的限制

重点注意的是在使用VisualStudio C++的时候,int main()定义一次在整个工程中只可以有一个

数组的定义:
一批具有同名的同属性的数据就组成了一个数组(array)。
数组中数据的排列是有一定规律的
数组中的每一个元素都是同样的数据类型

7-24号C语言学习笔记--------------------------------------------------------------------------
数组的学习笔记
怎样定义一个一维数组
类型说明符 数组名[常量表达式]
需要注意:数组的下标是从0开始的
常量表达式中可以包括:常量和常量符号
C语言不允许对数组的动态大小做定义
再使用:int a[10];表示在内存空间中划定了一个空间,如果用的Visual Studio C++的话
空间的值是4 * 10byte = 40byte

引用一维数组
应注意的是只能调用一个元素不可以一次整体地调用数组的整体的全部元素的值
引用数组的表现形式是:数组名[下标]

一维数组的初始化
定义:在定义数组的同时给数组赋值这称为数组的初始化
例如:int a[10] = {1,2,3,4,5,6,7,8,9,10};
其中花括号内的数据就是初始化列表

也可以只给数组的一部分元素赋值(其中没有赋值的元素的值是初始值0)
如果想要将一个数组中的全部元素赋值为0,我们可以使用:int a [10] = {0};其中没有赋值的元素自动是赋值为初始值0

在对数组实现初始化的时候由于已经制定了数组中元素,那么我们可以不指定数组的长度:
例如:int a[] = {12,3,34,4,45,5};表示数组a的长度是6

如果是字符型数组我们指定其初始值是0,如果是指针型数组我们指定其初始值是NULL;

冒泡排序算法详解
如果有N个数,那么需要进行n-1趟比较。同时在i趟比较中需要进行n -i 次两两比较

怎样定义一个二维数组
二维数组常称为矩阵
其定义的一般形式是:
int a[10][10];//表示的是其中 int 为类型说明符号;a表示的是数组名;两个10都是常量表达式。

C语言中定义一个二维数组时候可以看成一个一维数组,但是其有几个数组形式的元素
并且每一个元素又是一个一维数组(并且该数组包含的有元素)

二维数组中的元素的排列是按照顺序按行存放打,即在内存中先顺序存放第一行的元素,接着再存放
第二行的元素

在平时的矩阵形式是按照逻辑想像的,但是实际的存储形式是线性存储

引用二维数组
格式:数组名 [一维下标] [二维下标]
数组元素可以在表达式中同时也可以被赋值
二维度数组的初始化
方法:
int a[3][4] = { {1,32,3},{2,3,3,3}};
其中将打花括号中的第一个小花括号赋值给第一行;。。。

在使用数组初始化形式使用该形式:int a [3][4] = {1,2,3,34,4,45,5,5,5,5,5};的时候不容易观察
所以推荐使用第一种方法

二维数组中还可以对部分元素赋初值
例如使用:int a[3][4] = { {1},{2},{3}}; //表示的是将小花括号中的元素赋值给每一行的第一个元素
也可以对特定的元素进行赋值
例如:
int a[3][4] = { {1,2}{3}{0,23}}; //实现的是将花括号中的元素按照特定位置进行赋值
在赋值的时候需要可以中间的行数不赋值,例如:int a [3][4] = { {2,3},{},{3,4,5}};
表示的是将中间第二行隔过去了,没有赋值

当然在进行赋值的时候不可以将第二维的数省略但是第一维可以省略(此时系统根据实际的元素的情况得到第一维中的数字)

当然也可以只对部分元素赋初值而省略第一维的长度,同时应分行赋值(不可以不分行)
例如:int a [][4] = { {1,23},{2,3},{4,5}}; 从而实现赋值。

C语言中定义数组时候指定长度的时候可以使用int a [3 + 5];的形式,这一点是允许的
整型数组中默认值是0
在对数组进行赋值的时候由于已经指定相关的元素,此时可以不指定数组的长度
而是直接使用int a[] = {};
对于指针型数组来说,指定的是初始化为null
二维数组是逻辑上的行列表示但是在实际存储中是连续存放的
C语言中数组元素可以出现在表达式中,也可以被赋值
C语言中还可以对数组进行部分赋值
如果对所有的数组元素都赋初值,那么对第一维度的长度可以不指定但是第二维度的长度不能省略

9-13号字符数组学习笔记:==================================================================================
由于字符是由ASCII码存放的,所以可以使用整型数组来存放字符数据
字符数组的初始化:
字符数组中定义函数时没有赋值的元素自动默认赋值为’\0’
C语言中将字符串作为字符数组处理的结束标志
在遇到字符’\0’的时候表示字符数组的结束
C语言中使用数组存放字符串的时候会自动在最后加上一个’\0’作为结束标志
在ASCII码中’\0’字符表示的是空操作符,是不可以显示的
使用字符串常量来给字符数组进行赋值:char c[] = [“I am Happy!”] 或者使用
char c[] = “I am Happy!”;表示给数组c进行赋值
字符数组不包含\0也是合法的
但是为了测定字符串的实际长度,以及在程序中作相应的处理,在字符串中经常人为地加一个’\0’
字符数组的输入和输出:
(1):使用"%c"输入输出一个字符
(2):使用"%s"输入和输出string类型的字符串
用字符串作为结束标志的好处在于尽管字符数组长度很长但是还是只输出’\0’之前的字符串
如果定义的时候使用:
char str[13];
scanf("%s",str);
那么在输入:How are you?的时候会只有How进入数组,因为空格被当作’\0’输入
如果使用scanf("%s",&str);的时候需要知道的是,在C语言中数组名代表的是第一个数组元素的地址

几种常用的字符串函数:
1.puts(字符数组):作用是将一个字符串数组输出到终端
用puts()输出的时候可以包含转义字符

2.gets(字符串数组):得到终端输入的一个字符并得到一个函数值,该函数值是字符数组的起始地址

注意:使用puts()或gets()函数只可以输入输出一个字符
3.strcat函数(字符串连接函数)
strcat(字符数组1,字符数组2)

4.strcpy和strncpy函数-字符串复制函数
strcpy(字符数组1,字符串2),其中字符串1必须写成字符数组的形式,字符串2可以是一个字符串常量也可以是一个字符数组
在复制的时候如果字符数组1中未对其复制那么在复制之后,字符数组1中的前边几个元素是字符串数组2中的,但是字符串数组1的后边的
字符不一定是’\0’
不可以使用赋值语句实现将字符串赋值给字符数组
strcnpy(字符数组1,字符数组2,2)表示的是将字符数组2中的前两个元素复制到字符数组1中的前两个元素

5.strcmp()函数-字符串比较函数
其一般形式是:strcmp(字符串1,字符串2):表示比较两个字符串大小(从左向右)
在英文字典中位置在后面的字母比前面的字母的ASCII码大
小写字母比大写字母大

6.strlen()字符串组函数:测字符串长度的函数,得到的值是字符串的实际长度,而不包含’\0’在内

7.strlwr(字符串)函数转换为小写函数

8.strupr(字符串)-转换为大写的函数

/------------------------9-22号上午学习C语言笔记------------------------/
使用printf("%s,\n",c); 表示输出的是数组c中的第一个\0之前的元素
练习输出杨辉三角等代码(详见visual studio)

第七章函数调用:
注意在使用函数的时候需要注意如果在main函数之后才开始定义各种函数,那么在main函数中调用方法的时候需要注意的是
首先声明函数 例如:void testFunction();然后使用testFunction()即可实现函数调用
这样做的目的主要是告知编译系统

一个源程序文件可以被多个C程序调用
一个源程序文件是一个编译单位,C程序在执行的时候是以一个源程序文件进行编译的
C程序的执行是从main函数开始的,当调用完其他函数之后需要返回到main函数中,结束C程序的运行、

main函数是被操作系统调用的
不同的C语言编译系统提供的库函数的数量和功能会有一些不同,但是许多基本函数是相同的
函数体包括的是声明部分和语句部分
空函数设计的目的是:在函数的结构体中可以预留一些位置,然后在后续的过程中补充这些函数,从而使得程序的结构更加完整和容易扩充

7.3 调用函数:
函数名(实际参数列表)
按照函数在程序中出现的形式调用函数可以分为三类:
1.函数调用语句:
将函数调用单独作为一个语句
2.函数参数:
函数调用作为另一个函数的实际参数
3.函数表达式:
函数调用出现在另一个表达式中

在调用函数的过程中形参从实参得到值(这种数据传递称为”虚实结合“)
实参可以是常量、变量、表达式
实参和形参的类型应该相同或者赋值兼容
字符型和int型可以通用

函数调用的过程:
在定义函数的时候的形参,在函数没有调用的时候不占用内存空间
调用函数结束之后形参单元被释放,实参单元保留并维持原值,没有改变
实参向形参的数据传递是“值传递”,单向传递,只能由实参传给形参,而不能由形参传给实参
函数的返回值是通过return语句获得的
return 语句后面的值是一个表达式
函数类型决定返回值的类型
应当在编译阶段较多地发现错误。随之进行纠正错误
函数的首行称为函数原型
使用函数原型作为函数声明是C语言的一个重要特点
实际上,在函数声明的时候函数的形参名可以省写,而只写形参的类型
实际上只需要关注函数的类型即可,而不需要关注函数形参的类型
如果在程序开始已经声明了函数,那么在main函数中不再需要声明
写在函数外部的函数声明对整个文件范围内都有效
函数的嵌套调用:如果在主函数main中不需要直接使用max2函数那么只需要在max4中声明即可
函数的递归调用:C语言的特点之一就是允许函数的递归调用
函数递归调用的时候需要先回溯然后再进行递推即可得到想要的结果
递归调用求阶乘的代码见visual studio

汉诺塔问题的自己理解:
主要是解决大和尚移动自己的一个盘子并且解决其他的63个盘子的移动问题
其他的63个盘子的移动问题主要是需要递归处理,即对于每一个盘子的移动都是需要借助于其中一个然后移动到另外一个之上
也就是说定义的hanoi(int n,char one,char two,char three)函数的参数有四个:
{其中,n表示的是汉诺塔中盘子的个数;one,two,three表示的是:形式上的1,2,3个塔,但是需要根据实际问题实际确定}

//截止到9-22号晚上10:01

/------------------------------11-7号晚上学习笔记------------------------------/
实参可以是常量、变量或表达式
数组元素的作用和变量相当,一般来说凡是可以使用变量的地方都可以使用数组元素代替;此外,数组名可以作为实参和形参,传递的是数组
的第一个元素的地址
在用数组元素作为函数实参的时候,把实参的值传给形参,是"值传递"方式,其中,数据传递的方向是从实参到形参,是单向传递
7.7.2 一维数组名作为函数实参
使用数组名作为函数参数可以是实参和形参
使用数组元素作为函数参数的时候使用的是数组元素的值,而用数组名作为函数参数的时候使用的是数组元素的首地址
在函数的参数中指定形参数组的长度是没有意义的,因为C语言编译系统并不检查形参数组大小,而只是将实参数组的首元素的地址
传给形参数组名,形参数组名获得实参数组的首元素地址。
形参数组首元素地址和实参数组首元素地址指向的是同一个地址单元,具有相同的存储单元。
形参数组可以不指定大小,在定义数组时在数组民后面跟一个空的方括号。

/---------------------------11-8号上午学习笔记-----------------------------------/
在被调用函数中对形参数组定义时可以指定每一维的大小,也可以作为省略第一维度的大小说明(不可以省略二维数组中的第二维度的
大小原因是:在内存中数组是按照行进行存放的)
在第二维度大小相同的前提下,形参数组的第一维度可以与实参数组不同(解释原因:C语言不检查第一维度的大小)

//7.8局部变量和全局变量
定义变量的三种情况:{
1.在函数的的开头定义
2.在函数内的复合语句中定义
3.在函数的外部定义
}

主函数中定义的变量只在主函数中有效
在函数之外定义的变量是全局变量(也叫做:外部变量,其有效范围是:从定义变量的位置开始到本源文件结束)
设置全局变量的作用是增加了函数间数据联系的通道
全局变量定义习惯:一般是将第一个字母定义为大写
建议不是非必要不要使用全局变量:解释原因如下:{
1.全局变量在程序的全部实行过程中都占用了存储空间,而不是仅在需要的时候才开辟一块存储单元
2.使得函数的通用性降低了,因为再将一个包含有全局变量的函数移动到其他文件中时,还需要在新的文件中设置该全局变量,但是值得注意的是
此时不排除新定义的变量和该文件中原本存在的变量重名
3.使用全局变量过多会降低程序的清晰性
}

//7.9变量的存储方式和生存周期:
7.9.1 静态存储方式和动态存储方式:
内存中给供用户使用的存储空间情况:{程序区 静态存储区 动态存储区}
全局变量全部存放在静态存储区
在动态存储区存放的数据:{
1.函数形式参数
2.函数中定义的没有用关键字static 声明的变量,即自动变量。
3.函数调用时的现场保护和返回地址等
}

每一个函数中的局部变量的生存期并不等于整个程序的执行周期,它只是程序执行周期的一部分
C语言的存储类别包括以下4种:{
1.自动的
2.静态的
3.寄存器
4.外部的
}

7.9.2 局部变量的存储类别:
1.自动变量
不写关键字auto默认就是自动类别的,
2.静态局部变量

重点知识:
对于自动变量赋初值来说,不是在编译时进行的而是在函数调用时进行的,每调用一次函数重新给一次初值,相当于执行一次赋值语句
如果对于定义局部变量时不赋初值的情况,对于静态局部变量来说,编译时自动赋初值为0或空字符串’\0’
而对于自动变量来说它的值是一个不确定的值,因为每一次定义的时候,分配到的存储单元中的内容是不可知的
尽量不要过多使用静态局部变量
3.寄存器变量
寄存器变量的存取速度远远高于内存中存储变量

7.9.3 全局变量的存储类别:
一般来说外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。
1.在一个文件内扩展外部变量的作用域
如果定义外部变量的时候不是在程序开头处定义的,那么其作用域知识从定义处开始到文件结束
如果想在定义变量之前的程序中使用,需要使用的是关键字extern 对该变量作“外部变量声明”
在一个函数中使用extern A,B,C; 也可以实现对于变量的声明。不需要指定变量类型。
2.将外部变量的作用域扩展到其他文件中。
13 ** 3 表示的是幂次(使用的是FORTRAN语言表示幂次的方法)
编译器对于extern扩展的处理步骤:先看本文件中找外部变量的定义,找不到就在连接时从其他文件中找出外部变量的定义。如果从其他
文件中找到了,就将作用域扩展到本文件;如果找不到就是直接按出错处理
3.将外部变量的作用域限制在本文件中
将全局变量限制在本文件中的方法是:在定义的时候使用static关键字声明。
这种加上static声明,只能用于本文件的外部变量称为静态外部变量
对于局部变量声明变量的存储类型是为了实现对于变量存储方式的选择,但是对于全局变量来说,
声明变量的存储类型是为了实现对变量能否扩展问题的解决。

7.9.4 存储类别小结
从作用域角度来看,静态局部变量和静态外部变量的我作用域都是有局限的。

7.10 关于变量的声明和定义:
广义上来说,声明包括定义,但并不是所有的声明都是定义。
把建立存储空间的声明称为定义,而把不需要建立存储空间的声明称为声明。
一个简单的结论,在程序中凡是出现使用extern声明的变量都是狭义上的声明,除此之外都是定义。

7.11 外部函数和内部函数
7.11.1 内部函数:
在定义内部函数的时候需要在前边加上static关键字
内部函数又称为静态函数,可以使得内部函数的作用域只在本文件中

7.11.2 外部函数
在函数首部的最左端加上extern 关键字那么此函数是外部函数
C语言规定,如果在定义函数的时候省略了extern关键字那么默认是外部函数
函数原型通知编译系统:该函数在本文件中稍后定义,或在另一文件中定义。
使用#include的作用是:系统将函数原型集中在该文件中,并带上了其他需要的一些信息,那么用户在使用相关函数的时候只需要使用
#include 即可实现对于函数原型的声明。

你可能感兴趣的:(C语言学习,c语言)