指针基本介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ULT1NXs3-1684216911504)(…/TyPircture/1673827548462.png)]
指针的例子
对指针的加法,是在地址的角度增加了这个变量所对应的类型长度
会有随机垃圾值,是因为那个地址上没有分配一个对应的int 值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yMQ8fpRe-1684216911505)(…/TyPircture/1673831627403.png)]
char是一个字节,增加了一位数地址,那个地址上基于1025的二进制值,有00000100就是4
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zoxa47gI-1684216911505)(…/TyPircture/1673832785123.png)]
result::
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vlWkoYLJ-1684216911506)(…/TyPircture/1673832941820.png)]
void指针不能引用,也不能在地址上+*-
指向指针的指针
有关于“解引用”这个概念 *变量,意思就是:::去找这个变量所保存的值,那个值的号码对应的地址下面的值才是要寻找的值。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dy7SUgub-1684216911506)(…/TyPircture/1673839604961.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QgnQJ5Kd-1684216911507)(…/TyPircture/1673840366827.png)]
***r 解引用是 6,所以赋值语句可以执行
**q 和 *p 的解引用是10(前面先被赋值了所以不是6),加法语句可以执行
函数的值传递和参数传递:作用域的不同,定义的函数中的变量是在开辟的新一段内存(stack)中运行,结束后会自动释放,所以值传递不过来。
指针与数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CimzYDRA-1684216911507)(…/TyPircture/1673849490224.png)]
数组传参
因为数组可能很大,所以用传引用,只会取到数组的第一个元素(实际上只是传送数组的基地址),不用整个拷贝过来浪费内存。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v2CNQaTZ-1684216911508)(…/TyPircture/1673853042967.png)]
可以在被调函数中修改元素这种修改会体现到主调函数当中去
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dTpl1tq2-1684216911509)(…/TyPircture/1673852871792.png)]
指针与字符数组
#include<stdio.h>
void print(char* C)
{
int i = 0;
while(C[i] != '\0')
{
printf("%c",C[i]);
i++;
}
printf("\n");
}
int main()
{
char C[20] = "Hello";
print(C);
}
#include<stdio.h>
#include<string.h>
void print(char* C){ //void print(const char* C) 字符数组只能读不能改的做法
while(*C !='\0'){
printf("%c",*C);
C++;
}
printf("\n")
}
int main(){
char C[20] = "Hello"; //string gets stored in the space for array
char *C = "Hello"; //string gets stored as compile time constant
C[0] = 'A'; //error
print(C);
}
输出结果:Hello
指针与二维数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UY6K8g2y-1684216911509)(…/TyPircture/1673863072403.png)]
B[i][j] = *(B[i]+j) = *(*(B+i)+j)
B是指向一维数组的指针(其中一维数组包含了3个整型),B+1也是
指针与多维数组
上一节课的回顾
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qVmXJT5Y-1684216911510)(…/TyPircture/1673936620159.png)]
//多一个*号少一层嵌套
//c 第一个二维数组的地址 = 800 *c 第一个二维数组 即其中第一个一维数组的地址 = 800;*(*c)该一维数组即其中第一个变量的地址 = 800; *(*(*c))=2
//脱一个数组号[]就要加一个*号和+号(+那个脱的数组名)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qfePZnrN-1684216911510)(…/TyPircture/1673937399594.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zE9EjXkW-1684216911511)(…/TyPircture/1673938051582.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yysgupOM-1684216911511)(…/TyPircture/1673940032191.png)]
// *(c[0][1]+1) == *(*(*(B+0)+1)+1) B+0引用得到第一个一维数组的地址然后+1得到下一个数组(7和9)的地址引用得到7的地址然后再+1得到9的地址,然后再引用得到数值9
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XZKdXTO3-1684216911512)(…/TyPircture/1673940779921.png)]
多维数组传参
#include<stdio.h>
void Func(int A[][2][2]) //void Func(int (*A)[2][2]) 多维数组传参主要写后面的数字
{}
int main()
{
int C[3][2][2]={{{2,5},{7,9}},
{{3,4},{6,1}},
{{0,8},{11,13}}};
int A[2] = {1,2};
int B[2][3] = {{2,4,6},{5,7,8}};
Func(C);
return 0;
}
指针与动态内存
栈Vs堆
局部变量存储于栈中,静态局部变量存储于数据段(static/global)也是全局变量存储的地方
malloc返回的是一个void指针
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QKyd3uZ0-1684216911513)(…/TyPircture/1674025832526.png)]
malloc calloc realloc free
malloc
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cAgDf3Fr-1684216911513)(…/TyPircture/1674031882197.png)]
#include<stdio.h>
int main(){
int n;
printf("enter size of array\n");
scanf("%d",&n);
int* A = (int*)malloc(n*sizeof(int));
for(int i = 0;i<n;i++){
A[i] = i+1;
}
free(A);
A[2] = 6;
for(int i = 0;i<n;i++){
printf("%d",A[i]);
}
}
calloc
calloc申请了内存后会进行一段初始化,malloc要手动初始化,不然直接给垃圾值
calloc- void* calloc(size_t num,size_t size)
#include<stdio.h>
int main(){
int n;
printf("enter size of array\n");
scanf("%d",&n);
int* A = (int*)calloc(n,sizeof(int));
for(int i = 0;i<n;i++){
A[i] = i+1;
}
for(int i = 0;i<n;i++){
printf("%d",A[i]);
}
}
realloc
realloc指向已存在了的地址,拷贝后申请扩大一段内存
realloc- void* realloc(void* ptr,size_t size)
realloc传入恰当的函数可以是malloc和free的替代
int* B = (int*)realloc(NUll,n*sizeof(int))//0
#include<stdio.h>
int main(){
int n;
printf("enter size of array\n");
scanf("%d",&n);
int* A = (int*)malloc(n*sizeof(int));
for(int i = 0;i<n;i++){
A[i] = i+1;
}
int *B = (int*)realloc(A,2*n*sizeof(int))
for(int i = 0;i<n;i++){
printf("%d",B[i]);
}
}
内存泄漏
内存泄漏是不正当地使用动态内存或者内存的堆区,造成堆区垃圾越堆越多没有释放(未使用和未引用)
栈的内存会自动回收,栈的大小固定
#头文件 stdio、time、stdlib
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-76yyXF8D-1684216911514)(…/TyPircture/1674034997149.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P6KcR5dB-1684216911514)(…/TyPircture/1674035028101.png)]
函数返回指针
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-csMjACV3-1684216911515)(…/TyPircture/1674035818397.png)]
任何时候在执行的函数都是栈顶的函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wlJWZp0H-1684216911516)(…/TyPircture/1674036074362.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7dLLfjr7-1684216911516)(…/TyPircture/1674036874347.png)]
ptr那个地址,栈会自动释放,从函数返回指针要确保那个位置没有被释放or覆盖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IEKDnUNT-1684216911517)(…/TyPircture/1674036963785.png)]
函数指针
#include<stdio.h>
void A{
printf("Hello");
}
void B(void (*ptr)()){
ptr();
}
int main(){
B(A);
return 0;
}
为什么不直接调用A呢?回调的价值是什么
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6XOWx7BL-1684216911517)(…/TyPircture/1674045586499.png)]
基于ARM Cortex—M 指针及其应用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RCBOidlE-1684216911518)(…/TyPircture/1674047871428.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6iJGO4Fv-1684216911518)(…/TyPircture/1674048063034.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-36lUe9uU-1684216911519)(…/TyPircture/1674048196942.png)]
stdio.h>
void A{
printf(“Hello”);
}
void B(void (*ptr)()){
ptr();
}
int main(){
B(A);
return 0;
}
为什么不直接调用A呢?回调的价值是什么
[外链图片转存中...(img-6XOWx7BL-1684216911517)]
# 基于ARM Cortex—M 指针及其应用
[外链图片转存中...(img-RCBOidlE-1684216911518)]
[外链图片转存中...(img-6iJGO4Fv-1684216911518)]
[外链图片转存中...(img-36lUe9uU-1684216911519)]