03c_05day

03c_05day

===========================
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
int * p = &i;		//把int类型变量i的地址保存到指针p当中
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;
}
![06point](https://s2.loli.net/2022/08/16/7unBeUcYKkm3zog.png)
 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));//可以使用
	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;//把int类型变量i的地址保存到指针p当中
	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);

	//printf("*(&i) = %d\n", *(&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
19
20
21
22
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
	int i = 0;
	int *p = &i;//把int类型变量i的地址保存到指针p当中
	
	printf("i = %d &i = %p\n", i, &i);
	printf("*p = %d p = %p\n", *p, p);
	
	//*p = 9527;
	scanf("%d", p);

	printf("i = %d &i = %p\n", i, &i);
	printf("*p = %d p = %p\n", *p, p);

	//printf("*(&i) = %d\n", *(&i));//可以使用
	//printf("&(*i) = %d\n", &(*i));//不能使用

	return 0;
}
![09point](https://s2.loli.net/2022/08/16/CasOxBrYX1wSuvm.png)
 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;//p++;//p+=1;

	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;
}