初识指针-----生动地理解C语言的指针

初识指针

什么是指针:

        指针是用来存储内存地址的变量。可以使用 * 符号来声明一个指针变量。

        我们在定义一个普通变量时,都会有数据类型+变量名。但是,对于电脑来说,并不知道这个名字的含义。所以就需要一个能够让电脑认识的命令,同时代表这个变量。这时候,指针的作用就体现了。

对于指针更加生动的理解:

        咱们举个例子:变量名,就是一个人的名字,但是指针,是一个人的身份证号。

        咱们都知道,全局变量和局部变量可有相同的变量名,但是他们的内存地址不同。就像有两个姓名一样的人,但是他们的身份证号不同。

        当通过姓名叫人时,相同名字的人可能发生冲突,但通过叫身份证号,可以很快区分,体现在C语言中,这便是指针的有趣且重要的作用了。

对于指针的定义

        下面这段代码是之前定义普通变量时的形式

#include<stdio.h>
int main ()
{
	int a;//定义一个整型变量
	char b;//定义一个字符型变量
	
	
	return 0;
}

        下面这段代码是定义指针变量的格式

#include<stdio.h>
int main ()
{
	int *a;//定义一个整型指针变量
	char *b;//定义一个字符型指针变量
	
	
	return 0;
}

        所以咱们能够知道,定义指针变量和普通变量的其中一个区别是在变量名之前有一个 '*', 这个符号代表对指针变量的声明

取地址运算符和解引用运算符

        指针是存储内存地址的变量,那内存地址我们应该如何获取呢??

        因此,有一个运算符-----'&',叫取地址运算符。这个符号的作用,就是获取普通变量的内存地址。

#include<stdio.h>
int main ()
{
	int a = 10;//定义一个整型变量
	int *p;
	p = &a;//取a的内存地址,p指向a的内存地址

	
	
	return 0;
}

        在这段代码中,&a 获取了a的地址,并且指针p指向了a的地址。咱们可以通过变量名a访问内容,也可以通过指针的方式访问内容。

#include<stdio.h>
int main ()
{
	int a = 10;//定义一个整型变量
	int *p;
	p = &a;//取a的内存地址,p指向a的内存地址
	
	printf("%d\n",a);//通过变量名
	printf("%d\n",*p);//通过用户定义的指针
	printf("%d\n",*(&a));//通过指针

	
	
	return 0;
}

在上述代码中

第一个printf,就是通过常规的变量名进行内容的访问。

第二个printf,通过指针访问。

        我们可以看到一个面熟的符号 '*'。但是,这个和定义指针的符号含义不同。在这里,叫做解引用运算符,而在定义指针的语句中,只是对指针变量的声明,发挥声明作用。

        解引用运算符,我们可以理解为:通过身份证号,知道一个人的姓名。通过内存地址,我们可以知道指向的变量,并且输出对应的内容。

        通过对p指向的地址进行解引用,我们获取了变量的内容,通过'printf'输出。

第三个printf

        同时出现了'*''&',说明,这两个符号的作用是相反的。取地址运算符--&,获取a变量的内存地址,解引用运算符--*,对内存地址进行解引用,获取到对应内容,最后通过printf输出内容。

%p输出内存地址

#include<stdio.h>
int main ()
{
	int a = 10;//定义一个整型变量
	int *p;
	p = &a;//取a的内存地址,p指向a的内存地址
	
	printf("%p\n",p);
	printf("%p\n",&a);

	
	
	return 0;
}

可以看到,指针p指向的就是变量a的地址

指针的间接访问和变量名的直接访问

#include<stdio.h>
int main ()
{
	int a = 10;
	int *p = &a;
	printf("%d\n",a);
	printf("%d\n",*p);
	return 0;
}

指针p指向变量a的内存地址,通过解引用p指向的地址,间接对a的内容进行访问

指针的运算

在指针变量中:

        1.对于指针变量的运算,有意义的就是加,减。乘除是不被允许的,因为我们无法明确运算后的结果指向了什么位置。

        2.指针的运算与指针的类型相关。我们都知道,不同类型的变量在内存中占据不同的字节空间。整型int占据4个字节,字符型char占据1个字节,实型(浮点型)float占据4个字节

        所以,对于整型指针,每加一时,会向前移动4个字节。字符型指针,每加一,会想前移动1个字节。

#include<stdio.h>
int main ()
{
	int a = 10;//定义一个整型变量
	int *p;
	p = &a;//取a的内存地址,p指向a的内存地址
	
	printf("%p\n",p);//输出p指向的内存地址
	printf("%p\n",p+1);//输出运算后的内存地址

	
	
	return 0;
}

在数组中:

        咱们要知道,数组中的每一个元素,在内存中的内存地址都是连续的。

        如果要想用自己定义的指针指向数组中的元素,数据形式一点要相同。

整型数组,每个元素的内存地址相差4

#include<stdio.h>
int main ()
{
	int a[5] = {1,2,3,4,5};//定义一个整型数组
	int *p;//定义一个整型指针
	int *p2;
	p = &(a[0]);
	p2 = &(a[1]);
	
	printf("第一个元素的地址是:%p\n",p);
	printf("第二个元素的地址是:%p\n",p2);
	
	
	return 0;
}

字符型数组,在内存地址中每个元素的内存地址相差1

#include<stdio.h>
int main ()
{
	char a[5] = {'1','2','3','4','5'};//定义一个字符型数组
	char *p;//定义一个字符型指针
	char *p2;
	p = &(a[0]);
	p2 = &(a[1]);
	
	printf("第一个元素的地址是:%p\n",p);
	printf("第二个元素的地址是:%p\n",p2);
	
	
	return 0;
}

指针的初步运用

        运用指针实现数值的交换

        咱们先复习之前普通变量的数值交换

#include<stdio.h>

void exchange(int num1,int num2)
{
	int tmp = 0;
	tmp = num1;
	num1 = num2;
	num2 = tmp;
	printf("交换后的值:a = %d,b =%d\n",num1,num2);
	
}



int main ()
{
	int a =10;
	int b =20;
	exchange(a,b);
	
	return 0;
}

        接下来运用指针进行交换

#include<stdio.h>

void exchange(int *num1,int *num2)//定义两个整型指针,分别指向a,b的地址
{
	int tmp;
	//内存地址的交换
	tmp = *num1;
	*num1 = *num2;
	*num2 = tmp;
	
}



int main ()
{
	int a =10;
	int b =20;
	exchange(&a,&b);//传入a,b的内存地址
	printf("交换后的值:a = %d,b =%d\n",a,b);
	return 0;
}

        使用指针进行交换时,直接可以对内存地址进行交换,而不是进行变量名的内容交换。

        当内存地址修改时,指向的内容也会随之改变

        运用指针实现数组遍历

#include<stdio.h>
int main ()
{
	int arr[5] = {1,2,3,4,5};
	int *p;//定义一个整型指针
	int i;
	
	p = &(arr[0]);//用取地址运算符&,获取第一个元素的地址,p指向数组第一个元素的地址
	
	for(i = 0;i<5;i++){//for循环实现遍历
		printf("%d\n",*p);
		p++;
	}
	return 0;
}

数组与指针

数组名与指针相同和不同

相同:

        每一个数组名,代表数组的首地址,也就是指针。同时,每一个数组的第一个元素的地址,也代表该数组的首地址。所以,咱们可以直接用数组名代表指针,或者第一个元素进行数组的操作。

#include<stdio.h>
int main ()
{
	int arr[5] = {1,2,3,4,5};
	printf("%p\n",arr);
	printf("%p\n",&(arr[0]));

	return 0;
}

#include<stdio.h>
int main ()
{
	int arr[5] = {1,2,3,4,5};
	int *p = arr;//定义一个指针,指向数组
	printf("%p\n",arr);
	printf("%p\n",p);
	printf("%p\n",&(arr[0]));

	return 0;
}

不同点:

        数组名,相当于指针常量,不可运算;而指针,可以进行运算。

#include<stdio.h>
int main ()
{
	int arr[5] = {1,2,3,4,5};
	int *p = arr;//定义一个指针,指向数组
	
	arr++;
	printf("%p\n",arr);
	printf("%p\n",p);
	printf("%p\n",&(arr[0]));

	return 0;
}

结束语:

        OK,对于指针的初步认识,解释完毕,大家还有什么疑惑,评论区讨论或者私信。希望大家在以后的C语言学习生涯中,更上一层楼!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值