=========================== 2022-7-20 ===========================
指针(point/pointer)
1.指针的含义
嵌入式开发工程师需要遵守的规则
谁打开,谁关闭 文件IO
谁开辟,谁释放 堆区空间 malloc
谁创建,谁销毁 链表
谁加锁,谁解锁 线程
指针就是用来存储地址的
变量是用来存储数据的(会存在内存中<以二进制补码形式>)
指针是用来存储地址的(会存在内存中<以二进制补码形式>)
虽然在内存中以二进制补码的形式存储地址,
但是会以十六进制的方式展示给程序员
注意 :地址是没有负的(最小的地址0x00000000)
2.指针的定义
定义变量 type name;
定义指针 type * name;
数据类型 指针名 ;
1 2 3 4 5 6 7 8 9 char c ;int i ;floar f ; char * pc ;int * pi ;float * pf ;int * p int * p = &i;
3.通过sizeof了解指针的数据类型的特点
无论何种类型的指针,在我当前的机器上
打印出来的字节大小都是8个字节
我当前机器的CPU是64bit的CPU,安装的是64bit的Ubuntu系统
代表在我当前的机器中一个地址长度就是64bit
指针是用来存储地址的,所以指针应当能够存储64bit的地址
所以无论体积类型在我当前机器上都是8个字节
4.指针的命名规则和变量的命名规则一致
5.指针运算符
& 取地址的运算符(用来取地址的)
可以使用在变量\指针\数组成员
* 取值的运算符(用来取值的)
可以使用在地址
6.指针的赋值
变量名 = 数值 ;
1 2 3 4 5 6 c = 'A' ; i = 9527 ; f = 3.14 ; pc = &c ; pi = &i ; pf = &f ;
7.指针的初始化
1 2 3 4 5 6 7 8 9 char c = 'A' ;int i = 100 ;float f = 3.14 ;数据类型 指针名 = 地址 ; char * pc = &c ;int * pi = &i ;float * pf = &f ;int * p = NULL ;
注意 :如果初始化指针时,不确定指针指向哪个空间,
可以先将指针指向NULL(空)
NULL代表的就是空的意思,在ASCII表中表示的就是0x0
(其实就相当于给指针赋了一个地址0x0)
8.指针的定义和指针的初始化的区别(和变量的内容一样)
9.指针的使用
1>指针在使用时应当先定义再使用
2>指针应该保存相应数据类型变量的地址
int *类型的指针保存 int类型变量地址
char *类型的指针 保存 char类型变量地址
float *类型的指针 保存 float类型变量地址
3>指针可以做加减法运算(自增自减运算)
int *P;
p + 1; p += 1; P++; ++p;
注意 :不同类型的指针,在做加减法运算时,
所偏移的字节数是不同的,
和指针本身要保存的变量的数据类型有关
例子:
int *pi;//指针保存的地址是0x1000
pi++;
printf ("pi");//0x11004
10.特殊的指针
1>空类型的指针(万能指针)
void *p;
空类型的指针可以保存任意类型的地址,所以叫做万能指针
会在指针的强制类型转换时使用
2>空指针(指向NULL的指针)
在C语言中,不允许访问地址为NULL的存储空间,
因为该空间是系统保留的,所以不允许访问
操作空指针,程序在执行时会报段错误
3>野指针(没有对象的指针)
野指针指向一个已经删除或者已释放的空间
与空指针不同,没有办法通过简单的判断避免使用野指针
只能通过养成良好的编程习惯来尽力减少
可以主动的把已删除或者已释放的指针变为空指针
再去判断空指针即可
--------------------------------------------------------
在操作指针时,可以使用一些方法,避免使用空指针
可以加入判断
if(p == NULL)//if(NULL == p)
printf ("指针p是一个空指针!\n");
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i = 1 ; int sum = 0 ; loop: if (i <= 100 ) { sum += i++; goto loop; } printf ("sum = %d\n" , sum); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { printf ("sizeof(char *) = %ld\n" , sizeof (char *)); printf ("sizeof(short *) = %ld\n" , sizeof (short *)); printf ("sizeof(int *) = %ld\n" , sizeof (int *)); printf ("sizeof(long *) = %ld\n" , sizeof (long *)); printf ("sizeof(float *) = %ld\n" , sizeof (float *)); printf ("sizeof(double *) = %ld\n" , sizeof (double *)); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i = 0 ; printf ("i = %d &i = %p\n" , i, &i); i = 13 ; printf ("i = %d &i = %p\n" , i, &i); return 0 ; }

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i = 0 ; printf ("i = %d &i = %p\n" , i, &i); i = 13 ; printf ("i = %d &i = %p\n" , i, &i); printf ("&(*i) = %d\n" , &(*i)); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i = 0 ; int *p = &i; printf ("i = %d &i = %p\n" , i, &i); printf ("*p = %d p = %p\n" , *p, p); i = 13 ; printf ("i = %d &i = %p\n" , i, &i); printf ("*p = %d p = %p\n" , *p, p); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i = 0 ; int *p = &i; printf ("i = %d &i = %p\n" , i, &i); printf ("*p = %d p = %p\n" , *p, p); scanf ("%d" , p); printf ("i = %d &i = %p\n" , i, &i); printf ("*p = %d p = %p\n" , *p, p); return 0 ; }

1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int *p = 0x12345678 ; printf ("p = %p *p = %d\n" , p, *p); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { char *pc; short *ps; int *pi; long *pl; float *pf; double *pd; printf ("sizeof(pc) = %ld sizeof(*pc) = %ld\n" , sizeof (pc), sizeof (*pc)); printf ("sizeof(ps) = %ld sizeof(*ps) = %ld\n" , sizeof (ps), sizeof (*ps)); printf ("sizeof(pi) = %ld sizeof(*pi) = %ld\n" , sizeof (pi), sizeof (*pi)); printf ("sizeof(pl) = %ld sizeof(*pl) = %ld\n" , sizeof (pl), sizeof (*pl)); printf ("sizeof(pf) = %ld sizeof(*pf) = %ld\n" , sizeof (pf), sizeof (*pf)); printf ("sizeof(pd) = %ld sizeof(*pd) = %ld\n" , sizeof (pd), sizeof (*pd)); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i = 9527 ; char *p = &i; printf ("i = %d &i = %p\n" , i, &i); printf ("*p = %d p = %p\n" , *p, p); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { short i = 100 ; short *p = &i; printf ("i = %d &i = %p\n" , i, &i); printf ("*p = %d p = %p\n" , *p, p); ++p; printf ("i = %d &i = %p\n" , i, &i); printf ("*p = %d p = %p\n" , *p, p); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { char c = 0 ; short s = 0 ; int i = 0 ; long l = 0 ; float f = 0 ; double d = 0 ; void *p; p = &c; p = &s; p = &i; p = &l; p = &f; p = &d; return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i = 100 ; void *p = &i; printf ("p = %p\n" , p); printf ("*p = %d\n" , *p); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int *p = NULL ; *p = 100 ; printf ("*p = %d\n" , *p); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int *p = NULL ; p = malloc (sizeof (int )); *p = 100 ; printf ("free之前*p = %d\n" , *p); printf ("free之前p = %p\n" , p); free (p); p = NULL ; printf ("free之后*p = %d\n" , *p); printf ("free之后p = %p\n" , p); *p = 9527 ; printf ("free之后*p = %d\n" , *p); printf ("free之后p = %p\n" , p); return 0 ; }