Linux-C P7 指针

Linux-C P7 指针

在这里插入图片描述

指针涉及的内容很多,通过思维导图也能够了解到
从开始的指针的基础运算多级指针
数组指针指针数组来了解数组与指针之间的关系
后面还会讲到const指针void指针字符指针

指针基础及运算

在这里插入图片描述

指针概念

什么是指针?

指针就是用来存储地址变量,可以使程序简洁、紧凑、高效;有效地表示复杂的数据结构;实现动态分配内存;得到多于一个的函数返回值

地址又是什么?

说到地址,我们可以形象的理解一下,你要找一个人,需要先知道他家的地址在哪,然后才有可能在他家找到他,所以地址对于内存也是一样,通过地址,我们可以找到对应地址里的内容

指针变量

指针变量

专门用来存放地址的变量

指针变量的定义

为了使用指针变量需要先对指针变量进行定义

一般形式

数据类型 *变量名;
int *p;

这里定义了一个指针p,且返回的是整型(int)

指针变量的赋值

定义完之后,需要给指针变量赋值

指针变量的赋值有两种,接下来一一介绍

方式一

int *p;
p = &i;

方式二

int * p = &i;

关于指针的基本使用,通过下面的例子来了解一下

举个栗子

在这里插入图片描述

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int x = 50,y = 100;
	int *p1;
	p1 = &x;
	int *p2 = &y;

	printf("x = %d,*p1 = %d,&x = %p,p1 = %p,&p1 = %p\n",x,*p1,&x,p1,&p1);
	printf("y = %d,*p2 = %d,&y = %p,p2 = %p,&p2 = %p\n",y,*p2,&y,p2,&p2);

	return 0;
}

在这里插入图片描述
这里分别用了两种方法来赋值指针,然后分别输出两种赋值之后的内容和地址信息

可以看到x = *p1 ,&x = p1,&p1 =0xbfc0c2b8

具体的原因后面会给大家揭晓


关于&和*
前面的栗子里,分别输出了x和&x,p1、*p和&p,这些都代表什么呢?

为什么x与*p1的结果相同,&x和p1结果相同呢?

首先是

&——取地址运算符,获取变量对应的地址
*——指针运算符,获取地址里存储的变量

下面通过图来说明p,*p和&p之间的关系

p——指针变量,内容是地址量
*p——指针所指向的对象,内容是数据
&p——指针变量占用的存储区域的地址,即存放地址的地址

在这里插入图片描述
p1是变量x的地址
*p1是指针指向的内容
&p1是存放变量x的地址的地址

指针运算

关于指针的运算,指针能进行算术运算关系运算赋值运算,除了这些还有一些指针表达式

算术运算

运算符计算式意义
+p+n指针向地址大的方向移动n个数据
-p-n指针向地址小的方向移动n个数据
++p++或++p指针向地址大的方向移动1个数据
p–或--p指针向地址小的方向移动1个数据
-p-q两个指针之间相居左隔数据元素的个数

举个栗子

在这里插入图片描述

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int x = 50;
	int *p,*q;
	p = &x;
	q = p-2;

	printf("p = %p\n",p);
	printf("p+2 = %p,p-2 = %p\n",p+2,p-2);
	printf("p++ = %p,p-- = %p\n",p++,p--);
	printf("p-q = %p\n",p-q);
	return 0;
}

在这里插入图片描述

关系运算

运算符说明计算式
>大于p>q
<小于p<q
>=大于等于p>=q
<=小于等于p<=q
!=不等于p!=q
==等于p==q

举个栗子

在这里插入图片描述

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

int main(int argc, const char *argv[])
{
	char s[]="HelloWorld";
	char *p = NULL,*q = NULL,t;

	printf("%s\n",s);

	p = s;
	q = s + strlen(s) - 1;

	while(p < q){
		t = *p;
		*p = *q;
		*q = t;
		p++;
		q--;
	}

	printf("%s\n",s);

	return 0;
}

在这里插入图片描述

数组指针

在这里插入图片描述

指针与一维数组

什么是数组指针?

数组指针就是指向数组的指针,指针名就是指向数组的首地址

int a[10];
int *p;
p = a;

在这里插入图片描述

这里p+1指的是加一个数据类型的长度,而不是1bit

等价关系

数组名 + i --> 数组名[i]

举个栗子

在这里插入图片描述

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int a[10] = {0,1,2,3,4,5,6,7,8,9};
	int *p;
	int i,n;
	p = a; 
	n = sizeof(a)/sizeof(int);

	for(i = 0;i < n;i++){
		printf("a[%d] = %d,*(p + %d) = %d\n",i,a[i],i,*(p+i));
	}
	return 0;
}

在这里插入图片描述

常见等价操作

指针操作数组操作说明
array&array[0]数组首地址
*arrayarray[0]数组的首元素
array + i&array[i]数组第i个元素的地址
*(array + i)array[i]数组的第i个元素
*array + barray[0]+b数组首元素的值加b
*(array + i) + barray[i]+b数组第i个元素的值加b
*array++(当前指向第i个元素)array[i++]先取得第i个元素的值,i再加1
*++array(当前指向第i个元素)array[++i]先将i加1,再取得第i个元素的值
*array–(当前指向第i个元素)array[i–]先取得第i个元素的值,i再减1
*–array(当前指向第i个元素)array[–i]先将i减1,再取得第i个元素的值

指针与多维数组

二维数组指针

介绍完一维数组指针,平时还会用到二维数组指针

二维数组指针的一般形式

<数据类型> (*<指针变量名>)[表达式];

举个栗子

在这里插入图片描述

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int a[3][3] = {{0,1,2},{3,4,5},{6,7,8}};
	int i,j,m,n;
	int (*p)[3];

	p = a;
	m = sizeof(a)/sizeof(a[0]);
	n = sizeof(a[0])/sizeof(int);

	for(i = 0;i < m;i++){
		for(j = 0;j < n;j++){
			printf("%d %d %d ",a[i][j],*(*(a+i)+j),*(a[i]+j));
			printf("%d %d %d\n",p[i][j],*(*(p+i)+j),*(p[i]+j));
		}
		printf("\n");
	}
	return 0;
}

在这里插入图片描述

多级指针

多级指针定义

多级指针变量,一个指向指针的指针变量

对于指向处理数据的指针变量称为以及指针

指向向一级指针变量的指针变量称为二级指针

二级指针变量的基本形式

<数据类型> **<指针名>

多级指针运算

关于多级指针运算具体的运算原理,先来看个例子,再剖析他

举个栗子
在这里插入图片描述

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int x = 50;
	int *p;
	int **q;

	p = &x;
	q = &p;

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

	return 0;
}

在这里插入图片描述

在这里插入图片描述

指针数组

指针数组定义

指针数组是一个数组,每个数组元素存放一个指针变量

指针变量数组的一般说明形式

<存储类型> <数据类型> *<指针变量数组名>[<大小>]

指针数组运算

举个栗子

在这里插入图片描述

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int x = 50,y = 100;
	int *p[2];

	p[0] = &x;
	p[1] = &y;

	printf("x = %d,&x = %p\n",x,&x);
	printf("p[0] = %p,*p[0] = %d,&p[0] = %p\n",p[0],*p[0],&p[0]);
	printf("y = %d,&y = %p\n",y,&y);
	printf("p[1] = %p,*p[1] = %d,&p[1] = %p\n",p[1],*p[1],&p[1]);

	return 0;
}

在这里插入图片描述

const和void

在这里插入图片描述

const指针

用const修饰指针变量,会使得指针变量常量化

const指针用三种表示形式

常量化指针目标表达式

const <数据类型> *<指针变量名称>[=<指针运算表达式>]

使得指针不能修改指向变量的值

常量化指针变量

<数据类型> *const<指针变量名称>[=<指针运算表达式>];

使得指针不可以修改其地址

常量化指针变量及其目标表达式

const <数据类型> *const<指针变量名>=[<指针运算表达式>];

使得指针既不能修改指向变量的值,也不可以修改其地址

举个栗子

在这里插入图片描述

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int x = 50,y = 100;
	const int *p1;
	int *const p2;


	p1 = &x;
	printf("x = %d,&x = %p,*p1 = %d,p1 = %p\n",x,&x,*p1,p1);
	x++;
	printf("x = %d,&x = %p,*p1 = %d,p1 = %p\n",x,&x,*p1,p1);
	p1 = &y;
	printf("y = %d,&y = %p,*p1 = %d,p1 = %p\n",y,&y,*p1,p1);
	
	*p2 = &x;
	printf("x = %d,&x = %p,*p2 = %d,p2 = %p\n",x,&x,*p2,p2);
	x++;
	printf("x = %d,&x = %p,*p2 = %d,p2 = %p\n",x,&x,*p2,p2);
	*p2 = &y;
	printf("y = %d,&y = %p,*p2 = %d,p2 = %p\n",y,&y,*p2,p2);

	return 0;
}

在这里插入图片描述

void指针

void型的指针变量是一种不确定数据类型指针变量
定义变量的时候,通过类型来决定该变量所占的内存空间

一般形式

void *<指针变量名称>

null指针

如果一个指针不指向任何数据,我们就称之为空指针,用 **NULL **表示

NULL ((void *)0)

字符指针

在这里插入图片描述

字符串

通常借助于字符数组来存储字符串字符指针可以存储字符串的起始地址,即指针指向字符串第一个字符,这样,我们可以用指针来处理字符串

字符指针数组

若数组中存储了若干个字符串的地址,则这样的数组叫作字符指针数组

举个栗子

在这里插入图片描述

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

int main(int argc, const char *argv[])
{
	char s1[] = "Welcome";
	char s2[] = "to";
	char s3[] = "CagePan";

	char* a1[3] = {s1,s2,s3};
	char *a2[3] = {"Welcome","to","CagePan"};
	char **p;
	int i;

	p = a1;
	printf("array1:%s %s %s\n",a1[0],a1[1],a1[2]);
	for(i = 0;i < sizeof(a2)/sizeof(char *);i++){
		printf("%s ",*(p+i));
	}
	printf("\n");

	p = a2;
	printf("array2:%s %s %s\n",a2[0],a2[1],a2[2]);
	for(i = 0;i < sizeof(a2)/sizeof(char *);i++){
		printf("%s ",*(p+i));
	}
	printf("\n");


	return 0;
}

在这里插入图片描述

更多内容

Linux-C P1 Linux基础与Vi操作

Linux-C P2 数据类型

Linux-C P3 运算符和表达式

Linux-C P4 输入输出

Linux-C P5 控制语句

Linux-C P6 数组

Linux-C P8 函数

Linux-C P9 内存管理

Linux-C P10 结构体细讲

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CagePan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值