高级语言程序设计(C语言)

第一章.计算机的发展
世界上第一台计算机 1946年 美国:ENIAC电子数字积分计算机 电子管为主要元件 ,冯.诺依曼提出存储程序概念和二进制思想;
1.四个发展时代
1>第一代 :20世纪50年代,主要采用真空电子管制造计算机
2>第二代:20世纪50年代末期:出现了以晶体管为主要元件的第二代计算机;
3>第三代:1964年,IBM公司推出IBM360系列计算机垄断了60%~70%的国际市场,它的出现标志着计算机进入第三代;
4>第四代:随着大规模集成电路和微处理器的出现,计算机进入第四代;

2.计算机语言
1>机器语言:由二进制代码表示的能被计算机识别和执行的指令集合.如1000000加

2>汇编语言:
*1.利用助记符代替机器语言,同时具有占用存储空间较少,执行效率高的优点add a,b
*2.在汇编阶段,汇编程序 将 汇编语言编写的程序(源程序) 进行汇编,
转换为生成一个可重定位目标文件(目标程序);

3>高级语言:
*1.使用高级语言编写的程序称为"源程序",源程序无法被计算机直接运行.
必须翻译为二进制程序(目标程序)后才能执行;

*2.翻译程序通常有两种工作方式

①.编译方式:将源程序全部翻译成二进制代码(目标程序),然后再执行;先写完再翻译
在此完成翻译工作的程序称为“编译程序”(编译程序)

②.解释方式,翻译一句执行一句,边解释边执行(Basic语言);同步翻译,(解释程序)

*3.世界上第一个高级语言是Fortran语言,目前广泛运用的高级语言有c/c++,java和C#;

3.算法
1>概念:解决问题的步骤序列就是算法;

2>算法必须具备的五个特征:
①.可执行性(语法正确)
②.确定性(符合逻辑的)
③.有穷性(不能死循环)
④.有输入信息说明(有注释)
⑤.有输出信息的步骤;(每步都比较清晰)

3>算法描述方法
*1.自然语言(母语描述(文字)) 比较冗余,易出现歧义;

*2.传统流程图:
流程图是一些图形表示各种操作,用图形描述算法形象直观,易于理解.

*3.N~S流程图
三种基本结构:顺序结构,选择结构,循环结构.
①.顺序结构:A->B

②.选择结构:
二分支选择结构:(true P(判断条件) false) if(){}else{};
多分支选择结构: if()else if()else{}; switch case 语句

③.循环结构:
当型循环结构:when();p的true和false 为true就执行循环, false就停止循环
直到型循环: for(i=0,i<sum,i++);

*4.伪代码
是用介于自然语言和机器语言之间的文字和符号描述的算法.

*5.计算机语言(高级语言)
计算机是无法识别流程图和伪代码的,只有计算机语言编写的程序才能被计算机执行;

4.计算机程序
1>概念:简称程序,是根据算法描述,用计算机语言表示的能被计算机识别和执行的 指令集合 ;

//this is a c program
#include<stdio.h> //头文件 相当于import 导入库; 编译预处理
void main(){
printf("this is a c program.\n");
}

5.结构化程序设计方法的优点:
1>采用 "自顶向下,逐步求精" 的结构化程序设计方法使得整个设计方案层次分明,
可以 "先易后难,先抽象后具体" 使得整体程序设计工作,思路清晰,目标明确;

2>程序由 "相互独立的模块" 构成,在设计模块时不会受到其他模块的牵连;

6.面向对象程序设计 (自顶向下,逐步求精)
与传统的结构化设计思想的区别:
1>面向对象方法采用数据抽象和信息隐藏技术(封装)使组成类的数据和操作是不可分割的.
避免了结构化程序由于数据和过程分离引起的弊病;

2>面向对象的程序由类和对象(类的实例)和对象之间的动态联系组成的.
而结构化程序是由结构化数据,过程的定义以及调用过程处理相应的数据组成的.

第二章.C语言的基本知识
1.C语言发展
ALGOL60(20世纪60年代)->CPL组合程序设计语言(1963年) ->BCPL基本CPL(1970)->B语言->C语言(1972)
UNIX(1975)->正式(1978),83ANSIC C语言标准草案(1983)->C90(1990)-->C99(1999) 后面都是国际化

2.C语言基本词法
*1.字符集:
1>字符是组成语言最基本的元素.C语言的字符集由,字母,数字,空格,标点和特殊字符组成;
C语言的字符集就是ASCII字符集,主要包括:
*1.阿拉伯数字:0,1,2...,9(共10个);
*2.大小写英文字母:A~Z,a~z(共52个);
*3,非字母,非数字的可显示字符(33个);
2>关键字(小写)
*C语言区分大小写(敏感大小写)
C语言中具有特殊含义的单词称为"关键字",又称"保留字",主要用于构成语句.
C语言共有 32 个关键字,所有的关键字均由小写字母组成;(由系统定义,不能用作其他定义);

if else switch case break default for do while continue return void(无返回数)

char int short long float double enum extern(外部变量) const(常量) static

register(寄存器) signed(有符号(-,+)) unsigned(无符号) sizeof(计算字节数)

typedef(类型定义) struct(结构) union/'juːnjən/(共用) volatile /'vɒlətaɪl/(可变的)

auto(自动) goto(转向)

3>标识符

*1.用途:
标识符是字符的序列,除了库函数的函数名等由系统定义外,其余均由用户自行定义,
用户根据需要对C程序中用到的变量,符号变量,自定义函数等进行命名,形成用户标识符.

*2.概念:标识变量名,符号常量名,函数名,数组名,文件名的字符串序列;

*3.规则:
①.用户标识符仅由 大小写英文字母,数字和下划线组成,且第一个字符不能是数字;
②.大小写字母含义不同,一般用小写;
③.用户定义的标识符既不能是C语言的关键字,也不能与用户编写的函数或C语言的库函数重名;
*.标识符应该"见名知意,不易混淆";
*4.使用: 先定义,后使用;

3.C语言的特点:
1)结构化语言
2)运算能力强大
3)数据类型丰富
4)具有预处理能力
5)可移植性好
6)程序执行效率高
7)程序设计自由度大

4.分割符
C语言的分割符包括逗号(",")和空格(" ")两种,
1>逗号主要用于在类型说明和函数参数表中, int a,b;
2>分割各个变量;空格多用于语句各单词之间,作为分割符;int num;
3>语句的分割为分号(";")

5.常量
符号常量:用标识符代表常量:
1>一般用大写字母:PERICE、PI(π);

2>定义格式:#define 符号常量 常量;

3>其值在作用域内不能改变和再赋值;

4>符号变量的优点是:见名知意,一改全改;

#define PRICE 30
#include<stdio.h>
void main(){//程序的入口;
int num,total;//先声明,是为了分配存储空间
num=10;
total=num*PRICE;
printf("total=%d\n",total")
}

6.C语言基本语句分类
按语句功能或构成的不同,可将C语言分为

数据定义语句(定义变量),

赋值语句(从右往左读),

函数调用语句(调用方法),

表达式语句(if()else{},switch case..),

流程控制语句(goto),

复合语句(代码块{})

空语句(接口)

C语言的每个语句都以分号结束;

scanf:标准的输入函数;
printf:标准的输出函数;

&a的含义是取a的地址,&"取地址"

#index<stdio.h>
void main(){
int max(int x,int y)声明函数,如果max函数在main函数上面,该行可省略;
int a,b,c;
scanf("%d,%d"&a,&b);
c=max(a,b);
printf("max=%d",c);
}

int max(int x,int y){
int z;
if(x>y)z=x;
else z=y;
return (z);
}

7.C程序的基本组成及特点

1>每个C程序由一个或多个函数组成,每个C程序有且只有一个主函数,其函数名为main,
除主函数外,可以没有其他函数,也可以有一个或多个其他函数.

2>函数 是C程序的基本单位,每个函数是由函数首部和函数体两部分组成.

3>C程序中每一语句后面都以分号";"作为语句的结束,但预处理命令,函数首部和
右花括号"}"之间不能加分号.void main(){}

4>C语言本身没有输入/输出语句,而是通过调用库函数scanf()、printf()、
getchar()和putchar实现的;

5>C程序的任意位置都可以加注释/*...*/,注释可以多行但不可以嵌套;

6>C程序的书写格式灵活,一行内可书写多条语句,一条语句也可以写在多行上,
可以任意插入空格和回车;

7>C程序的执行总是从主函数开始,并在主函数结束.主函数和其他函数的位置是任意的,
其他函数总是通过函数调用语句被执行;

8>C程序中可以有预处理命令,通常预处理命令应放在程序的最前面.(#define,#include)

9>主函数可以调用任何其他函数,任何其他函数之间可以相互调用,但不能调用主函数;

8.C语言格式特点

1>习惯用小写字母,大小写敏感;

2>不使用行号,无程序行概念;

3>可使用空格和空行;

4>常用锯齿形书写格式

**.编程规范
1>使用Tab缩进;

2>{}对齐;

3>有足够的注释;

4>有合适的空行;

9.C程序的开发环境(运行步骤)

1>编辑: 进入C语言编译系统,建立源程序文件,扩展名为"c"或"cpp",
编辑并修改,保存源程序,

2>编译: 计算机不能识别和执行高级语言编写的源程序,必须经过 编译程序 对源程序
进行编译.

3>连接: 经过编译生成的目标程序还无法在计算机上直接运行,因为源程序中输入,输出
以及常用的海曙运算是直接调用的函数库中的库函数,因此必须把库函数的处理过程
链接到经编译生成的目标程序中,生成可执行文件,其扩展名为"exe".

4>运行: 一个C源程序经过编译,链接后生成可执行文件,可在编译系统或操作中运行;

10.编辑步骤:

File->New->Files->C++ source file->Add to project->空工程(工程名)->File(hello.c)->Ok

第三章 数据类型,运算符和表达式
1.数据类型

1>概念:数据既是程序加工和处理的对象,也是程序加工和处理的结果;

2>分类:

*1.基本类型:整型,浮点型(实型),字符型和枚举四种;

*2.构造类型是由基本数据类型按一定规则组合而成的复杂数据类型,
包括数组型,构造体类型和共用体类型;

*3.指针类型是一种更加灵活的数据类型,用来表示内存地址;

*4.空类型是从语法完整性角度给出的数据类型,表示不需要数据值,因而没有类型;

有符号短整型 short
有符号整型 有符号的基本整型 int E1=10;(E就是10)
有符号的长整型 long
整型
无符号短整型
基本类型 无符号整型 无符号的基本整型
无符号的长整型
单精度型float
实型(浮点型)
数 双精度型 double
据 字符型 char ASCII码值
类 枚举型enum
型 数组类型
构造类型 结构体类型 *.数据类型决定
共用体类型 1>数据占内存字节数
指针类型: 用来表示内存地址 2>数据取值范围
空类型void 3>可以进行的操作

2.常量
1>字符char常量
*. \n 回车换行, \r回车 \0空字符 \’单引号 \ddd 1~3位八进制进制代表的字符,例:\103,代表’C’
*. \t 横向跳下一制表符 \f 换页 \b 左退一格 \\ 反斜杠 \” 双引号 \Xhh 1~2位16进制代表的字符
*, C语言中空字符和空格符不同,空字符转义符用”\0”表示, 空格符是ASCII字符集中一个可显示字符,值为32;
2>字符串常量(用字符数组来存放)
编译时再字符串的末尾加一个转义字符’\0’,作为字符串结束标志,即长度为n个字符的字符串占n+1个字节;
也就是说字符串除了存储有效的字符外还要存储一个字符串结束标志’\0’; “abc”,声明字符数组时是char[4]

3>符号常量
#define 符号常量 一般放在程序的开头,每个定义必须独占一行,因为不是语句,没有”;” 例如:#define PRICE 30
特点:其值在作用域内不能改变和再赋值.
#define PRICE 30 //符号常量
#include <studio.h>
Void main(){
int num, total;
total=num*PRICE;
}
使用符合常量的优点:
*1.提高程序的可读性;
*2.便于程序修改;

3.变量
*1.定义:其值可以改变的量, 数据类型 变量名;
*2.变量应该有名字,并在内存中占据一定的存储单元;
*3.变量名和变量值有不同的含义(变量名为一个符号地址,)
1>整型变量
有符号的:int short long 无符号的:unsigned,unsigned short, unsigned long,(无符号的都为正数)
2>实型变量(浮点型)
*1.单精度:float,一般占用内存4字节,保留6~7位有效数字(a=123456.789 实际a的值为123456.7位).
*2.双精度double,一般占用内存8字节,保留15~16位有效数字(b=123456.789,实际b的值为123456.789)
*3.有效数字:从左边第一位非0数字起,开数,小数点不算;
3>字符型变量,占1字节,需要注意字符串只能是常量,C语言中没有字符串变量,而是用字符数组存放字符串变量;
4>变量的定义:
*1.被定义为整型(包括int short和long)的变量,若其值为-128~127,则可以作为字符型变量使用;
*2.被定义为无符号整型(包括unsigned、unsigned short, unsigned long,)的变量,
若值为0~255,也可以作为字符型变量使用;
*3.变量初始化:可以在定义是赋初值;编译程序根据变量定义为其分配指定字节的内存单元;
*4.先声明(在内存中开辟存储空间),再赋值
Int a=1; short s=8;

4.运算符:
1>运算符的分类
算术运算符:(+ - * / % +(取正) –(取负) )
自增,自减运算符: ++ --
基 关系运算符: (< <= == > >= !=)
本 逻辑运算符: ! && ||
运 运 位运算符: << >> ~ | &
算 算 赋值运算符 (= += -= *= /=)
符 符 条件运算符(?:)
逗号运算符(,)
数据长度运算符 (sizeof)

强制类型转换 (类型)
专 成员运算符:( . ->)
用 下标运算符([ ])
指针运算符(* &)

2>学习运算符应注意:
*1.运算符功能;;
*2.与运算量的关系;
①.要求运算量个数
②.要求运算量类型
*3.运算符优先级别;
*4.结合方向;
*除单目运算符(只有一个变量参与运算),赋值运算符和条件运算符是右结合之外,其他的运算符都是左结合.
*5.结果的类型;

3>C语言运算符的优先级的排序
1. () [] ->(指针运算) . 从左至右
2. ! ~ ++ -- *(取内容) &(取地址) +(取正) -(取负) sizeof 从右至左计算;
3. *(乘) / %(运算变量必须为整数)
4. +(加) -(减)
5. << >>
6. < <= > >=
7. == !=
8. &(位逻辑与) 从左至右
9. ^(异或)
10. |(位逻辑或)
11. &&
12. ||
13. ?: 从右至左
14. = += -= *= /= %= &= ^= |= >>= <<= 从右至左
15. , 从左至右

4>自增和自减 运算符
*1.如果 ++ 或 – 在前面就自增(减)后再参加运算;
*2.如果 ++ 或 – 在后面就先不自增(减)运算完成后再自增(减);
例: int a=2; int b=3;
(a++)+(++b)=2+4=6;然后a+1=3, ++在后不参与运算,(运算结束后起作用)

5>复合赋值运算符
a+=3;=> a=a+3 (两边等价)
1)10进制转为2进制, (将需要的数记为1,不需要的记为0)
1024 512 256 128 64 32 16 8 4 2 1
2)10进制转为2进制, (将需要的数记为1,不需要的记为0)
1024 512 256 128 64 32 16 8 4 2 1
例:47==> 0 1 0 1 1 1 1
如果是1byte(8位), 47就是0010 1111 (补了1位)
1byte 8位 如果10进制转为2进制后位不够就补0;

3)16进制 1 2 3 4 5 6 7 8 9 a(10 )b(11) c(12) d(13) e(14) f(15);

4)10进制 8进制 2进制 等
*1.将一个x进制整数anan-1..a1,转化成10进制的公式;
anan-1..a1=an*X(n-1)+an-1*X(n-2)+...a2*X+a;
例.0x11a=1*16^2+1*16^1+a*16^0=256+16+10=282;

*2.只计算其位不为0的数值;

*3.将一个10进制整数a,转换为一个x进制整数的公式: a/x取余,商/x取余,知道商为0,所有余数逆序即为x进制数;

*4.将一个10进制浮点数转换为一个2进制整数公式;
整数和小数分别转换,整数部分/2取余(商为0结束),小数部分*2取整(积的小数部分为0结束);


6>位移运算
<< (左移n位是乘以2的n次幂);
>> (右移n位是除以2的n次幂);

5.数据类型转换:
原则: 就高不就低或就长不就短
高 double float

long

unsigned

低 int char ,short

第四章 结构化程序设计
1.结构化程序设计方法
1)自顶向下,逐步求精
2)模块化设计
3)结构化编码:经模块化设计后进入编码阶段,任何程序都由顺序、选择和循环三种基本结构组成;

2.结构化程序三种基本结构:
1>三种基本结构:
1)顺序结构:程序的基本结构,它是按照书写顺序依次执行操作.
输入三角形边长,求面积(s=1/2(a+b+c), area=√s*(s-a)*(s-b)*(s-c)) sqrt(√) )
#include<math.h>
#include<stdio.h>
void main(){
float a,b,c,s,area;
scanf(“%f,%f,%f”,&a,&b,&c);
s=1.0/2*(a+b+c);
area=sqrt(s*(s-a)*(s-b)*(s-c));
printf(“a=%7.2f,b=%7.2f,c=%7.2f,s=%7.2f\n”,a,b,c,s);
printf(“area=%7.2f\n”area);
}
2)选择结构:分支结构,是根据某个或某些条件,从若干操作中选择某个操作执行的一种控制结构.
具体的,选择结构分为单分支选择结构,双分支选择结构和多分支选择结构三种;

3)循环结构是由控制条件控制循环体是否重复执行的一种控制结构.
循环结构分为当型循环结构,直到型循环结构和次数型循环结构三种;

2>九种控制语句
1) if(){}else{} (条件语句)
2) for()
3) while()
4) do~while()(循环语句 3)
5) continue (结束本次循环语句)
6) switch(多分支选择语句)
7) break(终止switch或循环语句)
8) goto(转向语句)
9) return(从函数返回语句)

3.函数调用语句
格式 :函数名(参数1,参数2,…参数n),
功能 :调用指定的库函数或用户自定义函数,对圆括号中的参数进行该函数指定的运算,运算结果作为函数的返回值返回;
本质上,函数调用语句是函数调用后面跟一个分号. 例:c=max(a,b);

4.表达式语句 int a=2; int b=a+2; (a>b)? a:b;

5.复合语句:if(){}else if(){}else{};大括号(“{}”)中的语句不会因为”;”结束,括号内的语句都会被执行
1>字符输出函数putchar(ch)
1)[调用格式]putchar(ch)使用它,必须在C源程序的开头加上编译预处理命令#include<stdio.h>或#include"stdio.h";
"ch"可以是一个整型变量,字符型变量,整型常量或字符型常量,也可以是转义字符或整型表达式,但不能是字符串;
2)[功能] 把一个字符输出到标准输出设备(显示器).此外,就功能而言它可以被”%c”格式说明符的printf()函数完全替代;
3)[返回值] 输出ch对应的单个字符; 一次输出一个字符

2>字符输出函数getchar()
1)[调用格式] getchar() 使用它,必须在C源程序的开头加上编译预处理命令#include<stdio.h>或#include”stdio.h”;
2)[功能] 从标准输入设备(键盘).输入一个字符,就功能而言它可以被”%c”格式说明符的scanf()函数完全替代;
3)[返回值] 输出的单个字符

3>printf(格式控制,输出表列)
%d—以有符号的十进制整数形式输出(正整数不输出”+”)
%o—以八进制无符号形式输出整型数据(不能输出前缀0)
%X/x—以十六进制无符号形式输出整型数据(不输出前缀0x)
%u –以十进制无符号形式输出整型数据
%f –以小数形式,小数部分为6位 %m.nf 占m宽,保留n位小数
%c -- 以字符形式输出
%s -- 以字符串形式输出

第五章:数组
1.定义:数组是具有相同数据类型的一组有序数据的集合.
1>数组中的数据称为数组元素,数组元素通过数组名和下标引用,下标是数组元素在数组中的位置序号,
表示该数组元素在数组中的相对位置;(下标从0开始)

2>声明 数组类型 数组名[常量表达式] int a[6] 数组名表示内存首地址,是地址常量;

3>一维数组元素的引用表示方法数组名[下标]

2.二维数组
1>声明: 数据类型符 数组名[行长度][列长度],…;
*1.数据类型可以是任何基本类型.
*2.数组名和变量名一样,必须遵守标识符的命名规则.
*3.行长度说明二维数组有几行,列长度说明二维数组有几列;行长度和列长度都是一个整型常量表达式,表达式中不能出现变量;
*4.二维数组的元素个数=行长度*列长度;
int a[2][3]={{1,2,3},{4,5,6}} 3行,4列 a[0][0],a[0][1],a[0][2], ,a[1][0]….
Int b[][3]={1,2,3,4,5};--intb[2][3]={{1,2,3},{4,5,0}};(没有赋值的默认为0(int的默认值))
*5.二维数组元素在内存中的排列顺序是”按行存放”,即先顺序存放第一行的各个元素,再存放第二行的各个元素,以此类推;
*6.可以把二维数组看做是一种特殊的一维数组,,其每个元素都是一个一维数组;
*7.一个数组定义语句中可以只定义一个二维数组,也可以定义多个二维数组,可以在一条定义语句中同时定义一维和二维数组,
同时还可以定义变量;
*8.二维数组的行列元素互换a[j][i]=b[i][j] int a[2][3]={{1,2,3},{4,5,6}}; int b[3][2]={{1,2},{3,4},{5,6}};

3.字符数组
1>gets(字符数组) 输入字符串
char a1[15]; gets(a1) 在scanf(“%s”,a1)中遇空格(\n)字符串便结束了,而gets()中,将空格作为字符存入字符型数组中;

2>puts(字符数组)->输出字符串
3>字符串比较函数strcmp
*1.格式:strcmp(str1,str2);
*2.功能:比较两个字符串;
*3.比较规则:对两个串从左到右逐个字符比较(ASCII码),直到遇到不同字符或’\0’为止.
*4.返回值:返回int型整数,其值是ASCII码的差值
a.若str1<str2,返回负整数; b. 若str1>str2,返回正整数; c. 若str1==str2,返回0;
*字符串比较不能用”==”,必须用strcmp(str1,str2);

4>strcpy(字符数组名,字符串[,整型表达式])(复制字符串)
将字符串赋值给字符数组(字符数组名,且字符数组的长度必须>字符串的长度);

5>strcat(字符数组名,字符串)(连接字符串)
将字符串连接到字符数组中字符串的尾端(最后一个有效字符的后面)
6>strlen(字符串)字符串长度,不包含’\0’ ;
7>strlwr(字符串) 将字符串中的大写写字母转换成小写字符串
8>strupr(字符串)将字符串中的小写字母转换成大写字母(-32)65~97

第六章函数
1.函数之间,没有从属关系,互相独立,不能嵌套定义,有且只有一个main函数,且结束和开始都是main函数;
2.分为库函数和用户函数、有参函数和无参函数、有返回值和无返回值函数;
3.格式:函数首部+函数体:
数据类型(无:void) 函数名(形式参数表) 函数首部{
函数体
数据定义语句部分;
执行语句部分;
}

形参:定义函数时函数名后面括号中的变量名, 实参:调用函数时函数名括号中的表达式;max(a,b)->实参,
void max(int x,int y)->形参;

用户函数如果在main()之前可以不做函数声明,但如果在main()下面的话就要在main()中声明函数, 数据类型 函数名(参数列表)

4.变量的存储类型
C语言中变量的存储类型为自动性(auto),寄存器型(register)(定义局部变量),外部型(extren)和静态型(static);
变量的存储方式分为静态存储方式和动态存储方式两大类.(静态,每次改变会保留,动态不会保留,用完释放)
自动型和寄存器型变量属于动态存储方式 ;
外部型变量和静态型变量属于静态存储方式 ;

第七章 指针
1.定义:C语言中的指针是一种数据类型(X86占4字节,X64占8字节)
*1.它与其他变量的不同就在于它的值是一个内存地址,
*2.变量&&地址&&内存宽度; 指针指定了内存地址和内存宽度(由指针类型决定(int 内存宽度就是4字节))
指针-->内存地址+内存宽度; 例 .i 地址 0x108 ,int i=10; int *p=&i;-->p(0x108) ;
printf(“p:%p,&i:%p,sizeof(p):%d\n”,p,&i,sizeof(p));

1>计算机系统的内存拥有大量的存储单元(每个存储单元的大小为1字节),为了便于管理,
必须为每个存储单元编号,该编号就是存储单元的"地址",每个存储单元拥有一个唯一的地址.

2>指针变量除了可以存放变量的地址外,还可以存放其他数据的地址,例如可以存放数组和函数的地址.

3>指针变量:int *p; int a; p=&a(将a的地址给指针p,p存储a地址的首地址);

4>指针变量定义的一般形式:

*1.[格式] 数据类型符 *指针变量名[=初始地址值],...;

①.声名:数据类型 *变量名 (int *p) ; int b[6]; int *p[];

②.赋值 p=&a --[a为int型变量] p=b;

③.使用:*p就是取被存储地址的内容,也就是*p==a;

*2.[功能]定义指向"数据类型符"的变量或数组的指针变量,同时为其赋初值;

*3.注意事项

①."*"表示定义的是一个指针变量,指针变量的前面必须由"*"号.

②.在定义指针变量的同时也可以定义普通变量或数组等;

③."数据类型符"是指针变量所指向变量的数据类型,可以是任何基本数据类型,也可以是其他数据类型;

④."初始地址值" 通常是"&变量名" "&数组元素" 或"一维数组名",这里的变量或数组必须是已定义的.

⑤.在定义指针变量时,可以只给部分指针变量赋初值.

⑥.指针变量的初始化,除了可以是已定义变量的地址,也可以是已初始化的同类型的指针变量,也可以是NULL(空指针);

⑦.指针变量初始化时,指针变量的"数据类型符" 必须与其"初始地址值"中保存的数据的类型相同;

2.指针变量的初始化
1>一般形式:[存储类型] 数据类型 *指针名=初始化地址;
例 int I; int *p=&i; int *q=p; 不能用auto变量的地址去初始化static型指针;
&取地址运算符,它是单目运算符,取地址运算符的运算对象必须是已定义的变量或数组元素,但不能是数组名,
运算结果是运算对象的地址;
int a[10]; *a=a[0] 数组名就是数组的首地址; &是获取变量的地址, *是取指针的内容是什么;

2>取地址符(&) 的结合性是从右往左; int a; int *p=&a; ++p;是向下在走一个地址;
“&”(reference)取引用地址, “*”(dereference)解析引用地址的值;

3>解引用运算符(“*”)
“*”解引用运算符(通过指针找到对应内存和里面存放的数据类)
*p1==>就是p1(内存地址)中的值,(取内存地址中的内容) *p改变也就是指针p对应内存地址中的值改变了.
那该内存对应的变量值也改变了;
例.int a,*p; a=10; p=&a;-->*p==10 ,if(*p+1)-->a=11|if(*p-1)-->a=9;
指针p指向内存地址的首地址基本类型就是变量a的地址->&a;
对指针指向地址内容的修改:
*1.“*”解引用运算符作用的指针p指向的内存地址不能是NULL(*void)或野指针;
*2.char *s=”Hello World” *s=“X”(error) 因为字符串存储在静态常量区,不能被修改;
*3.对*p的运算操作-->就是对指针p所指向的内存地址中的内容进行运算操作;
-->也就是改变了所有引用该内存地址变量的值;
*4.*&a==a;
void func(char *p)//此处*p是定义指针(形参是指针变量){
Printf(“%c\n”,*p);//取值(取指针p所指向的内存地址的值);
}

4>指针的赋值和使用
char i,j,*p1,*p2;
i='a';j='b';p1=&i; p2=&j; *p1=*p2;(地址没变,只是值一样了),
p1=p2-->p2=>P1(p2的地址赋给p1) p2和p1都指向同一个内存地址;

5>指针类型的互相转换
int *p1=&a; char *p2=(char*)p1
p1和p2的长度(内存宽度不同p1是4个字节宽度,p2的内存宽度是1个字节)不同,可访问的宽度也不同;
void*p指针没有内存宽度;(优点可以接收任何类型的指针的赋值)

6>sizeof(p)-->指针的长度(x86 4byte, x64 8byte), sizeof(*p):指针对应类型的长度;

7>指针的加减运算(只支持加减运算)
对于指针p,指针的加法运算p=p+n(或者p+=n)中,p向前移动的距离不是n个字节,
而是n个指针的单位长度,即n*sizeof(*p)个字节,减法反之;
二级指针: int a=10; int *p=&a; int**pp=&p ; pp-->p--a 指针作为实参时,必须传二级指针;

8>指针和数组
数组的指针是指向数组在内存的起始地址,数组元素的指针是指向数组元素在内存的起始地址
若将指针变量指向一维数组,可以采用以下两种方法:
*1.在数据定义语句中用赋初值的方式,即*指针变量=数组名
*2.在程序中用赋值的方式,即指针变量=数组名;

第八章 内存管理
1.系统虚拟内存空间布局
1)2GB内核空间
2)64kB非法区域
3)进程空间
4)64KB NULL空间

2.内存分类(由低到高)
1)栈及增长方向(Stack)
2)空闲区
3)堆(非连续区域)(heap)
4)代码(code)区
5)静态区(.data/.bss/.rdata);

3.堆和栈的区别
1>内存分配:
栈:由系统自动分配与回收,int b=0;增长有高到低,声名和释放有系统管理;
堆:malloc/free,地址由低到高;声名要调用malloc函数,释放要调用free函数;

2>大小限制
栈:应用层1M到10M,内核层:12K到24K不等
堆:受限于计算机系统中有效的虚拟内存;

3>效率比较
栈:由系统自动分配,速度较快,但程序员是无法控制;
堆:速度比较慢,而且容易产生内存存片;(容易产生内存泄漏);

4>存放内容
栈:用以记录程序执行时函数调用过程中的活动记录(栈帧),参数,返回地址,ebp,局部变量等;
堆:一般是在堆的头部用一个字节存放堆的大小,剩余部分存储的内容由程序员根据程序计算的需要决定;

4.内存地址的分类
1)逻辑地址:段地址+段内偏移组成
2)线性地址:由逻辑地址转换而来;
3)物理地址:CPU放出的电平讯号;

5.内存的寻址模式
1)分段模型 在16位系统中 16位寄存器存储不够,需要用两个完成,需要偏移地址(造成分段) seg<<4(对应16)+Offset
2)扁平模型 在32位中寄存器也是32位,不用再分段
3)实模式(对应分段模型)
4)保护模式(对应扁平模型)


6.内存分配
1)静态区-->全局基本类型变量
2)栈--->局部变量
3)堆-->char *p=(char *)malloc(256); //分配256个字节内存
If(p==NULL)return
free(p)释放内存 调用malloc需要用头文件 #include <malloc.h>
4)内存泄漏

 

posted @ 2023-11-28 17:16  R-Bear  阅读(187)  评论(0编辑  收藏  举报