指针

回顾

1.野指针

野指针的指向的地址是随机的,不能操作野指针
指针指向的地址是系统分配的,定义变量的时候向系统申请,系统进行分配
指针初始化的地址不能由自己给出

#include <stdio.h>
#include <stdLib.h>
#include <string.h>

int main()
{
	
	// 野指针是指没有初始化(赋值)的指针
	
	int *p; // 定义一个指针变量p   
	// *p 指向的是指针变量存储的地址对应的空间
	// 指针变量p没有存储地址,所以p中存储的地址是随机的(指针的指向是随机的)
	// 将这样没有初始化的指针称之为野指针
	*p = 200;
	
	system("pause");
	return 0;
}

2.零指针

  • int *p = NULL -- 表明定义了一个指针,并将其初始化为NULL,就是指向0所在的地址0x0000 0000;
  • 零指针初始化所指向的位置不用于存储其他的地址,只是表明该指针进行了初始化,可以进行使用的标志
  • 习惯:将指针使用完之后,置为NULL,这样在使用指针的时候,判断指针指向为NULL,那么该指针可以进行使用,如果该指针不为NULL,表明该指针不能使用(该指针未初始化或者正在使用)

#include <stdio.h>
#include <stdLib.h>
#include <string.h>

int main()
{	
	// 定义一个整型变量,如果不知道存储什么值,可以将a初始化为0
	int a = 0;
	// 定义一个指针变量p,如果不知道指针存储谁的地址可以将其
	// 初始化为0指针,将指针指向0地址,0x00000000 -- NULL
	int *p = NULL;
	
	// *p = 200; // 也不对,p保存了0x000000000,0x00000000是进行初始化的标记,该地址指向的空间不存储值
	
	// NULL是指针初始化的标记,指针p指向NULL,表示该指针初始化了,该指针可以使用,
	// 如果指针 p !== NULL 表明该指针没有初始化,不能使用(或者该指针指向其他地址空间)
	// 好习惯:将指针用完之后将指针变量指向NULL
	if(p == NULL)  
	{
		p = &a;
	}
	system("pause");
	return 0;
}

3. 万能指针

  • 可以保存任何地址的指针
  • void *p

#include <stdio.h>
#include <stdLib.h>
#include <string.h>

int main()
{	
	
	// 万能指针,可以保存任意的地址
	int a = 10;
        void *p;
        p = (void *)&a;
        // printf("%d\n",*p); // 编译出错,指针的类型是void *,取出的长度为sizeof(void)
        // sizeof(void) -- 编译器不知道多大 -- 编译出错
        
        // p指针变量保存的是a的地址,p的类型是void *类型
        // 想要取出p中的变量 -- 需要将p指针类型从void * 转为int *
        printf("%d\n",*(int *)p); // *(地址) -- 将地址进行强转 *((int *)地址)
        

        // 不可以定义void类型的变量
        // 但是可以定义void *类型,因为指针都是4个字节
        // void b; 出错
        void *b;
	
	system("pause");
	return 0;
}

  • 通过万能指针取内容的时候,需要将万能指针类型转变为取值的指针类型

4.const修饰的指针变量

  • const -- 修饰变量a之后,不能通过a变量名修改a在内存中的值
  • 但是可以通过地址进行修改a的内容
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{	
	// const修饰变量a,不能再通过a修改a内存里面的内容
	// 但是可以同过地址进行修改a的值
	const int a = 10;
	
	int *p = &a;
	*p = 100;
	
	printf("%d\n",a); // 100
	system("pause");
	return 0;
}
  • const int p = &a -- const修饰,不能通过*p修改指向空间的内容
  • int * const p = &a -- const修饰指针变量p,p中所保存的地址不可被修改

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
	int a = 10;
	
	int b = 20;
	// const修饰的是*还是变量p?
	// 这里修饰的是*
	const int *p = &a;  // 不能通过*p修改p所指向的空间的内容
	
	// *p = 100;  const修饰*之后,不能通过p修改p指向的空间的内容
	
	// const 修饰指针变量p
	// p保存的地址不可以被修改
	int * const p = &a;   
	p = &b;  // p保存的地址不可以被修改 
	
        // p本身的指向不能改变,不同通过*p修改p所指向的空间的内容
	const int *const p = &a;        

	system("pause");
	return 0;
}

5.多级指针