三下五除二带你初学C语言(11)——指针

我滴个娘,指针也太难了吧,自从我学了指针,我就一直弄不明白,导致没有信心,什么课程都学的和屎一样,接下来我必须要弄明白了!奥利给!为了迪奥、香奈儿、Mac、LV、神仙水冲冲冲冲冲冲·冲!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

指针到底是个啥子?
指针就是内存地址,咱们用指针访问变量其实是对内存中的数据进行操作。
这样就提高程序的运行速度和操作的灵活性呗!

首先请问,访问内存的数据有哪几种方式?
答:两种 直接和间接访问
直接:就是通过变量来实现,变量是内存中某一块存储区域的名称;
间接:通过指针实现,指针不是存储数据的,指针存储的是数据在内存中的地址,酱紫,我们可以通过访问指针达到访问内存中数据的目的

误区一 指针的类型
从语法角度,我们把指针声明语句里的指针名字去掉,剩下的部分就是指针的类型。
int * p; //指针的类型是 int *
float p; //指针的类型是 float
char p; //指针的类型是 char
注意:学过指针但是学艺不精的小伙伴们请注意啦!int p,不是说代表指针,int类型哦!(赶紧忘掉、忘掉)
正确解释: 这个p的类型是 int 指向整型的指针类型*
误区二 指针所指向的类型
当通过指针来访问所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
从语法角度,只需要把指针声明语句中指针的名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。
int * p; //指针所指向的类型是 int *
float p; //指针所指向的类型是 float
char p; //指针所指向的类型是 char
在指针的算术运算中,指针所指向的类型是有很大的作用滴
指针的类型(指针本身的类型)和指针所指向的类型是两个概念。弄不明白接下来的学习就会越来越糊涂,所以一定要弄清楚哦!

误区三 指针的值
指针的值是指针本身存储的数值(一般咱们用指针是要指针指向的值),话先说回来,指针本身的值被编译器当做的是一个地址,而不是一个一般的数值,就是这个指针所指向的这片内存区域的首地址,长度为sizeof(指针所指向的类型)

所以以后,遇到每一个指针,都应该思考,这个指针的类型是做什么?指针所指向的类型是什么?该指针指向了哪里??

***********************************************************GO!

一、指针的算术运算
指针的算术运算包括:指针与整数的运算、指针与指针的运算
1.1 指针与整数的运算
适用条件:适用于指向数组中某个元素的指针。
因为数组中元素存储于连续内存的位置中,后面元素的地址大于前面元素的地址,因此,我们很容易看出,对一个指针加一,使他指向下一个元素,加五使它右移动五个元素位置,把一个指针减三,向左移动三个元素位置,依次类推,对整数进行拓展,保证对指针进行加法运算能产生这种结果,而不管数组元素的长度如何。
如果指向数组前或后元素,虽然合法但是访问失败
例: p+n、 p-1
注:因为指向的是位置,所以指针加一减一是指针类型的个数进行加减(比如一个int + 4)
在这里插入图片描述

//指针
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
	int a = 1, b = 10;
	int *p1, *p2;
	p1 = &a, p2 = &b;/*指针赋值*/
	printf("p1的地址是%d      p1存储的值是%d\n", p1, *p1);//这里的*代表把指针里的值取出的意思
	printf("p2的地址是%d      p2存储的值是%d\n", p2, *p2);
	printf("p1-1的地址是%d\n", p1 - 1);
	printf("p1-1的地址存储的值是%d\n", *(p1-1));
	printf("p1-1地址中的值减1是%d\n", *p1 - 1);
	system("pause");
}

在这里插入图片描述
1.2 指针与指针的运算
如下图p2-p1结果是5,就是j-i 位置距离的值
在这里插入图片描述
二、运算符&和*
2.1 取址运算符 & p=&a; 就是指针p指向a的地址
2.2 间接访问运算符 *在这里插入图片描述
(*p)++ 对值进行加 只要变量和指针是对应的,一个变另一个值也变化
在这里插入图片描述
*p++ 对地址进行加
在这里插入图片描述
三、指针表达式
在这里插入图片描述
下面代码是用指针对a,b,c进行排序的算法
用指针p1p2p3来通过交换所指向地址的位置来输出相应的值,而不改变a,b,c的值

//指针
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
	int a = 5, b = 0, c = 9;
	int *p1, *p2, *p3,*p;
	p1 = &a;
	p2 = &b;
	p3 = &c;
	if (*p1 > *p2)
	{
		p = p2;
		p2 = p1;
		p1 = p;
	}
	if (*p1 > *p3)
	{
		p = p1;
		p1 = p3;
		p3 = p;
	}
	if (*p2 > *p3)
	{
		p = p2;
		p2 = p3;
		p3 = p;
	}
	printf("%4d%4d%4d\n", a, b, c);
	printf("%4d%4d%4d", *p1, *p2, *p3);
	system("pause");
}

在这里插入图片描述
***********************************************************GO!
四、数组指针
因为数组是占据内存中连续的存储区域,所以使用指针将使我们操作数组元素的手段更加丰富!声明指针来指向数组
当指针变量里存放一个数组的首地址时,此指针变量成为数组的指针变量,简称数组的指针
声明与赋值
例:
int a[5],*p;
p=&a[0]; 或·p=a;
p+1就是指向a[1], p+2就是指向a[2].

*p就是a[0], * (p+1) 就是a[1] *(p+i) 就是a[i]
数组表示指针变量的方法:
在这里插入图片描述
数组指针作为函数参数:
在这里插入图片描述
交换数组的值

//指针
#include <stdio.h>
#include <iostream>
using namespace std;
void wasp( int *p, int n)              //*p 就是数组的首地址
{
	int *i, *j, t;
	for (i = p, j = p + n - 1; i < j; i++, j--)    //其实和数值差不多的思想
	{
		t = *i;           
		*i = *j;
		*j = t;
	}

}
int main()
{
	int a[7] = { 1,2,3,4,5,6,7 };
	int i;
	for (i = 0; i < 7; i++)
	{
		cout << a [i];
	}
	cout << endl;
	wasp  ( a, 7);       //传进一个数组,函数用指针相匹配的
	for (i = 0; i < 7; i++)
	{
		cout << a[i];
	}
	system("pause");
}

在这里插入图片描述
综合应用——报数游戏
有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报道3的人退出圈子,问最后留下的那位是原来的第几号。

//指针
#include <stdio.h>
#include <iostream>
using namespace std;
# define N 50
int main()
{
	int num[N];
	int *p;
	p = num;
	int i=0, j=0,t=0, k=0,n;
	cout << "请输入人员个数n:";
	scanf_s("%d", &n);
	for (i = 0; i < n; i++)
		*(p + i) = i + 1;
	i = 0;
	 while (k <n - 1)
	{
		if (*(p+i)!=0)
		{
			t++;
		}
		if (t == 3)
		{
			*(p + i) = 0;
			t = 0;
			k++;
		}
		
		i++;
		if (i == n)
			i = 0;
	}
	while (*p == 0)
		p++;
	printf("%d",*p);
	system("pause");
}

在这里插入图片描述
五、指针与函数
函数指针是指向函数的指针变量。在C中,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。
函数指针的定义如下:
在这里插入图片描述
这个其实我基本没有遇到过,所以就懒得敲代码啦!嘿嘿嘿
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
六、指针函数
函数可以返回很多类型的值,我们就把返回指针类型的函数叫做指针函数
定义形式如下:
在这里插入图片描述
求两个数组的最大值和位置

//指针
#include <stdio.h>
#include <iostream>
using namespace std;
int *max(int x[], int y[], int *p, int *c)
{
	int i;
	int *m = &x[0];
		for (i = 0;i < 9; i++)
		{
			if (*m < x[i])
			{
				*m = x[i];
				*p = i;
				*c= 1;
			}
		}
		for (i = 0; i < 9; i++)
		{
			if (*m < y[i])
			{
				*m = y[i];
				*p = i;
				*c = 2;
			}
		}
		return m;
}
int main()
{
	int c1[10] = { 1,2,3,4,5,6,7,8,9,0 };
	int c2[10] = { 11,12,13,14,15,16,17,18,19,10 };
	int n;
	int c;
	int *p;
	p = max(c1, c2, &n, &c);
	printf("两个数组中最大的是%d,在%d数组中的%d位置", *p, c, n);
	system("pause");
}

在这里插入图片描述
七、指向函数的指针作为函数的参数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
加油!!!冲冲冲!!!


版权声明:本文为weixin_47716102原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。