C语言--指针初阶

C语言–指针初阶

文章目录

  • C语言--指针初阶
  • 一、指针是什么
  • 二、指针与内存的关系
    • 1.什么是内存
    • 2.什么是指针变量
    • 3.指针变量的使用
    • 4.指针变量的大小如何判断
  • 三、指针类型
    • 1. 指针类型的意义
    • 2. 野指针
      • 2.1 野指针的成因
      • 2.2 如何避免野指针
  • 四、指针的运算
    • 1. 指针 ± 整数
    • 2. 指针-指针
      • 2.1 案例一:求字符串的长度
    • 3. 指针的关系运算
      • 3.1 案例一:指针比较大小
  • 五、指针与数组的关系
  • 六、二级指针
  • 七、指针数组
    • 1. 使用指针数组模拟3行4列的数组


一、指针是什么

  1. 指针是内存单元中一个最小单元的编号,也就是地址,地址唯一标识一块内存空间
  2. 指针的大小是固定的4\8个字节(32位平台\64位平台)
  3. 平时口语的指针,通常指的是指针变量,是用来存放内存地址的变量

二、指针与内存的关系

1.什么是内存

内存就是电脑上的存储设备,例如买电脑的时候会告诉你,这个电脑是4/8/16/32G的内存,程序在运行的时候会加载到内存中,也会使用内存空间
C语言--指针初阶_第1张图片

2.什么是指针变量

C语言--指针初阶_第2张图片

  1. 指针变量是一种变量,是专门用来存放地址的
  2. int* pa = &a; //pa就被称为指针变量,因为a是整型类型,所以pa变量的类型就是int*

3.指针变量的使用

#include
int main()
{
	int a = 10;
	int* pa = &a;
	printf("%p\n", &a);
	printf("%p\n", pa);
	*pa = 20;//*--解引用操作
	printf("%d\n", a);
	return 0;
}

4.指针变量的大小如何判断

对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是(1或者0);
那么32根地址线产生的地址就会是:
C语言--指针初阶_第3张图片

  1. 在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节。
  2. 那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。

三、指针类型

1. 指针类型的意义

  1. 指针类型决定了指针进行解引用操作的时候,一次性访问几个字节
  2. char*的指针,解引用访问1个字节
  3. int*的指针,解引用访问4个字节
  4. float*的指针,解引用访问4个字节
    C语言--指针初阶_第4张图片
  5. 指针类型决定指针的步长(指针+1到底跳过几个字节)
    C语言--指针初阶_第5张图片
  6. 对于指针类型的应用(按字节更改变量)
#include
int main()
{
	int a = 0x11223344;
	char* pc = (char*)&a;//a是整数类型,用char*访问的时候,要进行强制类型转换
	int i = 0;
	for (i = 0; i < 4; i++)//字符类型,+1跳过一个字节
	{
		*pc = 0;
		pc++;
	}
	printf("%d", a);
	return 0;
}

2. 野指针

概念:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)

2.1 野指针的成因

  1. 指针未初始化
int main()
{
    int* p;
    *p = 20;
    renturn 0;
}

p是一个局部变量,没有初始化,里边是随机值

  1. 指针的越界访问
#include
int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	int* p = arr;
	int i = 0;
	for (i = 0; i <= 10; i++)
	{
		printf("%d ", *p);
		p++;
	}
	return 0;
}

C语言--指针初阶_第6张图片

  1. 指针指向的空间释放
    C语言--指针初阶_第7张图片

2.2 如何避免野指针

  1. 指针初始化
#include
int main()
{
	int a = 10;
	int* pa = &a;//指针的初始化
	
	int* p = NULL;//NULL-空指针,专门用来初始化指针
	if (p != NULL)
	{
		//这是指针的正确用法,如果直接对空指针进行赋值操作
		//*p = 20; 这样是不会成功的,因为NULL代表空,空指针也是地址,只是不能使用的地址
	}
	return 0;
}
  1. 小心指针越界
  2. 指针指向空间释放,及时置NULL
  3. 避免返回局部变量的地址
  4. 指针使用之前检查有效性

四、指针的运算

1. 指针 ± 整数

#define _CRT_SECURE_NO_WARNINGS 1
#include
#define N_VALUES 5
int main()
{
	float values[N_VALUES];
	float* vp;
	//指针+-整数;指针的关系运算
	for (vp = &values[0]; vp < &values[N_VALUES];)
	{
		*vp++ = 0;
	}
	return 0;
}

C语言--指针初阶_第8张图片

2. 指针-指针

  • 前提是两个指针要指向同一块空间(指针类型要相同)

  • 指针-指针的绝对值,得到的是两个指针之间的元素个数

#include
int main()
{
	int arr[10] = { 0 };
	printf("%d\n", &arr[9] - &arr[0]);
	return 0;
}

C语言--指针初阶_第9张图片

2.1 案例一:求字符串的长度

#define _CRT_SECURE_NO_WARNINGS 1
#include
int my_strlen(char* str)
{
	int count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	char arr[] = "abcdef";
	int len =  my_strlen(arr);
	printf("%d\n", len );
	return 0;
}

C语言--指针初阶_第10张图片
采用指针相减的方法

#include
int my_strlen(char* str)
{
	char* start = str;
	while (*str != '\0')
	{
		str++;
	}
	return str - start;
}
int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

3. 指针的关系运算

3.1 案例一:指针比较大小

#include
#define N_VALUES 5
int main()
{
	float values[N_VALUES];
	float* vp;
	for (vp = &values[N_VALUES]; vp > &values[0]; )
	{
		*--vp = 0;
	}
	return 0;
}

C语言--指针初阶_第11张图片

五、指针与数组的关系

  1. 指针和数组是不同的对象
    指针是一种变量,存放地址的,大小是4/8字节的
    数组是一组相同类型元素的集合,是可以存放多个元素的,大小取决于元素个数和元素的类型

  2. 数组的数组名是数组首元素的地址,地址是可以存放在指针变量中,可以通过指针访问数组

#include
int main()
{
	int arr[10] = { 0 };
	int* p = arr;
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
	{
		*p = i + 1;
		p++;
	}
	p = arr;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *p);
		p++;
	}
	return 0;
}

C语言--指针初阶_第12张图片

六、二级指针

#include
int main()
{
    int a = 10;
    int * pa = &a;
    int * * ppa = &pa;//ppa就是二级指针
    int** *pppa = &ppa;
    return 0;
}

C语言--指针初阶_第13张图片

七、指针数组

指针数组是数组,是存放指针的数组

#include
int main()
{
	//int arr[5] = { 1,2,3,4,5 };
	int a = 10;
	int b = 20;
	int c = 30;
	int d = 40;
	int f = 50;
	int* arr[5] = { &a,&b,&c,&d,&f };
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", *(arr[i]));
	}
	return 0;
}

1. 使用指针数组模拟3行4列的数组

#include
int main()
{
	int a[] = { 1,2,3,4 };
	int b[] = { 2,3,4,5, };
	int c[] = { 3,4,5,6 };
	int* arr[3] = { a,b,c };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

C语言--指针初阶_第14张图片

你可能感兴趣的:(C语言,c语言,开发语言)