指针的复习

指针是什么?

首先内存的细分:是由一个个字节的内存单元,每一个内存单元都有自己的地址。
指针的复习_第1张图片
指针是什么?
指针是变量,用来存放内存单元的地址。

#include
int main()
{
  int a=10;//在内存中开辟一块空间
  //这里我们对变量a,取出它的地址,可以使用&操作符.
  //将a的地址放在p变量中,p就是一个指针变量.
  int* p=&a;        
  
  return 0;
}

指针能表示的大小其实是地址线的位数决定的。
32位的平台下,指针表示的大小就是4个字节。64就是8个字节。

指针的数据类型是什么?

可以分为整形指针,字符指针,数组指针,函数指针等。

整形指针 字符指针

这两个是比较常见和容易理解的指针,依次用int和char表示,他们的区别在于指向变量类型不同,内存也不一样,在进行解引用操作时访问的字节大小也因为变量类型的区别会有所差异。整型指针可以访问4个字节,而字符指针只能访问1个字节。也就是说对整型指针变量解引用,一次可以操作一个整型,而对字符变量解引用一次只能操作一个字符。

较为特殊的charp="hello"这并不是将整个字符串的地址传个了p,而是传了字符串首元素‘h’的地址,可以通过’h‘的地址来找到整个字符串。此时出现charp2=“hello”,p2和p代表的是同一处地址,因为hello是常量字符串,没有必要开辟两块不同的空间的来存储它。这是字符指针的一个特性。

void指针

void型的指针可以接受任何类型的地址,但是不能对void型指针进行解引用操作。解引用操作要有特定的访问字节的数量,比如对整型指针解引用就是访问4个字节,字符型指针解引用就是访问1个字节,而void型指针无法确定访问字节个数,所以不能进行解引用操作。同时void*这种类型的指针也不能进行加减整数的操作,因为无法确定跳过的字节个数。

数组指针

数组指针本质是指针,用法: int (*p) [10] 。表示它指向数组的指针。这个数组中含有10个元素,每个元素都是整形。
区别于指针数组:
int * p[10]。表示的是指针数组,这个数组有10个元素,每一个元素都是整形的指针。

指针的大小与类型是否有关:

无关。
32的编译器:指针只能是32位的四个字节大小。

指针类型的意义是什么?

  1. 若指针类型为int * 的指针+1,那么它将跳过4个字节的大小指向4个字节以后的内容:
    指针的复习_第2张图片
    若指针类型为char*的指针+1,那么它只会跳过1个字节的大小指向下一个字节的内容。

  2. 解引用
    指针的类型决定了指针向前或向后走一步有多大距离。
    指针的类型决定了指针在进行解引用操作时,能向后访问的空间大小.

野指针

成因:

  1. 指针没有初始化
#include
int main()
{
  int* p;
  *p=10;
  return 0;
}
  1. 指针越界访问:当指针指向的范围超出arr数组时,p就是野指针。
#include
int main()
{
   int arr[10] = { 0 };
   int* p = &arr[0];
   int i = 0;
   for (i = 0; i < 11; i++)
   {
   	*p++ = i;
   }
   return 0;
}
  1. 指针指向的空间被释放
#include
int* test()
{
	int a = 10;
	return &a;
}
int main()
{
	int* p = test();
	return 0;
}

指针变量p得到地址后,地址指向的空间已经释放了,所以这个时候的p就是野指针。(局部变量出了自己的作用域就被释放了)

如何规避野指针

  1. 指针初始化
    当指针明确知道要存放某一变量地址时,在创建指针变量时就存放该变量地址。

当不知道指针将要用于存放哪一变量地址时,在创建指针变量时应置为空指针(NULL)

#include
int main()
{
	int a = 10;
	int* p1 = &a;//明确知道存放某一地址
	int* p2 = NULL;//不知道存放哪一地址时置为空指针
	return 0;
}
  1. 小心指针越界
  2. 指针指向的空间被释放后及时置为NULL

指针的运算

  1. 指针 + - 整数
#include
int main()
{
   int arr[5] = { 0 };
   int* p = arr;
   int i = 0;
   for (i = 0; i < 5; i++)
   {
   	*(p + i) = arr[i];
   }
   return 0;
}
  1. 指针关系的运算
    指针的关系运算,即指针之间的大小比较。
    我们如果要将一个数组中的元素全部置0,可以有两种方法。
    第一种:从前向后置0
#include
int main()
{
	int arr[5] = { 1, 2, 3, 4, 5 };
	int* p = &arr[0];
	for (p = &arr[0]; p <= &arr[4]; p++)
	{
		*p = 0;
	}
	return 0;
}

指针和数组

:数组名表示的是数组首元素的地址.

int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr;//p存放的是数组首元素的地址

二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?这就是二级指针
指针的复习_第3张图片
指针的复习_第4张图片

指针数组

指针的复习_第5张图片
来源于:
https://blog.csdn.net/m0_58367586/article/details/128289887

你可能感兴趣的:(C语言,linux)