一.数组作为参数
二.内存四区模型
流程说明
1、操作系统把物理硬盘代码load到内存
2、操作系统把c代码分成四个区
3、操作系统找到main函数入口执行
1.指针指向谁,就把谁的地址赋给指针。
2.指针变量和他指向的内存空间变量是不同的概念
三.指针
1.指针做函数参数,形参有多级指针,只需分配4个字节内存。当使用内存时,才关心指向的内存时一维,二维。
2.间接赋值的条件
条件一定义了两个变量
条件二 建立关联
条件三 *p
四.字符串
1.c语言的字符串是以0结尾
2.在c语言中没有字符串类型,通过字符数组模拟字符串
3.字符串的内存分配 堆 栈 全局区
4.strlen长度不包括0,sizeof 内存块大小
五.[ ]与*本质一样,都是操作内存
数组的首地址是只读常量,是一个常量指针,不可更改。
六.一级指针的操作模型
strcpy(a,b) 把b内存的数考到a的内存
七.项目开发字符串模型
1.strstr -whiledowhile
//char *p=”abcd1113333abcd”;求字符串中abcd出现的次数
// strstr();//查找出现第一次的位置
demo
int main()
{ int ncount;
char *p=”abcd1113333abcdqqqq3333abcd”;//p初始化
do
{
p=strstr(p,”abcd”);从指针位置开始,查找abcd字符串,返回abcd第一次出现的位置
if(p!=NULL)
{
ncount++;
p=p+strlen(“abcd”);//指针后移
}
}
while( *p!=’\0’) ;
printf(“%d”,ncount)
};
int count(char* p,char* b,int* a)
{
char *temp =p;
while(temp=strstr(temp,b) )
{
*a=*a+1;
temp=temp+strlen(“abcd”);
if(*temp==’\0’)
{
break;
return a;
}
}
}
不能轻易改变形参的值,再定义一个变量接替,返回值通过指针返回
八:1.通过递归的方式,逆向打印
理解递归,参数的入栈模型,函数的嵌套调用返回流程
2递归和全局变量(把逆序的结果存入全局变量)
3. 递归和非全局变量,使用指针做函数参数
九:一级指针模型易错分析(重点)
十:二级指针做输入输出模型
二级指针的输入,就是一级指针取地址,二级指针指向的内存是地址(一级指针的值);主调用函数分配内存
二级指针做输入第一种模型 指针数组
char *myarray[10]
数组中的每个元素都是指针,指针数组,数组排序改变的是指针的指向
二级指针做输入第二种模型 char myarray[10][30]. 二维数组
myarray [i] 是myarray [i] [j] 的地址 所以他是一个地址的数组,就是指针数组,也是二级指针
与第一种指针的步长不一样,步长为一行(30)指针指向内存空间的数据类型不一样 交换的是内存块
二级指针做输入第三种模型
自己malloc内存 char p =(char)malloc( sizeof(char*) * num) 指针数组 一维
p[i]=(char*) malloc( sizeof(char) * 100)内存数组 细分内存
把内存空间地址给指针就是指针指向内存
char **p=(char **)malloc(10sizeof(char));
if(p==NULL)
for (i=0;i<=10,i++)
{
p[i]=(char )malloc(sizeof(char30));//指针可以加【】往后移
if(p[i]=NULL)
}
多级指针避免野指针
使用多出口,判断是哪一次分配出错,进行不同的free操作
先释放一级指针p[i],再释放二级指针p
十一.数组类型
十二,数组类型指针 指向数组的指针
1.通过数组类型定义数组指针
typedef int(MYINT5)[5] MYINT5 * pointer 指向数组
2.声明一个数组指针类型
typedef int(*MYINT)[5]. MYINT5 mypoint
4.直接定义数组指针
int (*pmyarray)[5] 指向数组的指针。数组指针变量
十三.多维数组的本质
1.a[3][5] a多维数组名的本质就是一个数组指针。 a+1往后跳了20个字节(一行的5列 每个4个字节)
定义一个指向数组的指针变量
int (*pmyarray)[5] //告诉编译器给我分配4个字节的内存
pmyarray = a;
a+i代表整个第i行地址 二级指针 二级指针
*(a+i)代表一级指针。第i行首元素地址 只不过第一行整个行的地址和第一行首元素地址重叠
(a+i)+ j相当于&a[i][j]
[ ]相当于
2.多维数组做参数退化过程 退化为一个数组指针
十四.指针数组应用场景
十五.结构体
定义一个结构体struct teacher{
char name[ 64];
int age;
id;
};
这是定义了一个数据类型
struct teacher t1;
typedef struct teacher{
char name[ 64];
int age;
id;
} teacher;
teacher t1;
初始化变量
teacher t1={“aa”,31,11};定义变量,直接初始化
通过指针的方式操作内存空间
teacher *p =NULL;定义结构体指针
p=&t1;
p->age;
结构体嵌入一级指针和二级指针
结构体的深copy和浅copy
浅拷贝:只会拷贝指针地址 编译器的=只会吧指针变量的值拷贝,不会执行内存空间的拷贝
如果想执行深copy,需要显示分配内存
6.结构体的高级话题
偏移量 一旦结构体定义下来,结构体内成员的内存布局就定下来了
可以通过成员的地址求大的结构体内存
两个指针不能相减 强制转换int再减
十六.文件操作
按数据的组织形式
文本文件 ascii
二进制文件
2. 文件api分类
fgetc fputc 按照字符读写文件
fputs fgets 按照行读写文件(配置文件)
fread fwirte 按照块读写文件 (大数据块迁移 )
3. 配置文件读写库的实践
非对称加密 加密的密钥和解密的不一样 运算速度慢 强度大
明文 秘文 密钥
十七.动态库
头文件做的是连接作用
动态库与静态库
让其他程序来使用
1. 动态库
.dll 逻辑代码 加载 运行时加载到代码中 程序本身(exe)
dll是个应用程序 必须由exe来运行
#pragma comment(lib,”***.lib”)
2.静态库
.lib 逻辑代码。 在编译完成之后就已经存在程序之中 程序本身会变大