指针与变量和一维数组

1. 山雨欲来风满楼(指针要来了)

您(假如是颖颖)现在处于7#216教室,如果您的心上人(假如是彬彬)来看望您,假设有两种情况存在:
(1)他只知道您的名字
(2)他知道您当前所处的位置
哪一种情况下,他找到您的效率最高?
我们现在要去某个地方(例如七十二潭),常常先打开百度地图,规划好路线,其实这个路线恰恰就是定位目的地所处的位置。如果仅仅知道目的地,则需要费一番功夫才能到达。
大一来报到时,给你说7号楼,你也找不到呀,但如果给你提供了具体路线,你就可以轻易到达。
先来看一个程序,运行一下看看结果。

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

我们知道,预计int a=4; 定义了一个整型变量a,系统会在内存中为a开辟空间,则该空间的名称为a,4为该空间中存储的数据。从运行结果可知,给a开辟的空间的首地址为12ff44。根据前面的分析,我们想到:可以根据变量名a来找到a,显然也可以根据地址12ff44来找到a呀!那么,如何根据地址来找到a呢?人是有智能的,可以根据地址去找寻。但计算机该怎么办呢?

2. 指针驾到,速来接驾

针对上述程序,采用指针如下:

#include<stdio.h>
int main()
{
	int a=4;
	int *p;
	p=&a;
	printf("%d\n",a);
	printf("%d\n",*p); //*p是对指针变量p所指向的变量进行引用
	*p=9;
	printf("%d\n",a);
	return 0;
}

因为a为int,想通过a的地址来访问a,则需要定义一个指针变量p,int* p;(p为变量名,*告诉编译器p为指针变量,int则说明p指向的空间里面存放的是int类型的数据。
这里所说的指向是一个形象化的描述,因为p的空间中存放的是a的地址,根据该地址可以找到a,所以形象地认为p指向了变量a的空间。
需要注意:(1)指针和指针变量的区别:指针是地址,而指针变量是存放地址的变量。指针变量也有自己的地址。

#include<stdio.h>
int main()
{
	int a=4;
	int *p;
	p=&a;
	printf("%x\n",&a);  //变量a在内存中的地址
	printf("%x\n",p); //变量p空间中存放的数据
	printf("%x\n",&p); //变量p在内存中的地址
	return 0;
}

也可以采用格式%p输出地址值。可以根据sizeof§看看指针变量所占的字节数。

思考:
double a=3.5;
double* p=&a;//把a的地址赋值给指针变量p
p=a;//这条语句合法吗?

3. 指针性格开朗,广泛交友

3.1指针与变量

1. 通过指针变量给所指向的变量赋值

#include<stdio.h>
int main()
{
	int i=2,j=3,*p,*q;
	p=&i;
	q=&j;
	printf("i=%d,j=%d\n",i,j);
	printf("*p=%d,*q=%d\n",*p,*q);
	scanf("%d%d",p,q);
	printf("i=%d,j=%d\n",i,j);
	printf("*p=%d,*q=%d\n",*p,*q);
	return 0;
}

通过scanf("%d%d",p,q);给i和j输入了新的数据。

2. 可以改变指针变量的指向

#include<stdio.h>
int main()
{
	int i=2,j=3,*p,*q,*m;
	p=&i;
	q=&j;
    printf("%d,%d\n",*p,*q);
	m=p;p=q;q=m;
	printf("%d,%d\n",*p,*q);
	return 0;
}

通过三条语句m=p; p=q; q=m;改变了p和q的指向。

3. 通过指针变量来改变其所指向的变量的值

#include<stdio.h>
int main()
{
	int i=2,j=3,*p,*q,m;
	p=&i;
	q=&j;
	m=*p;*p=*q;*q=m;
	printf("%d,%d\n",*p,*q);
	return 0;
}

通过三条语句m=*p;*p=*q;*q=m;改变了p和q所指向空间的数据。
你是否想起了函数那一章的swap()交换函数???

3.2指针与一维数组

针对求最值问题,讲述指针对一维数组的三种操作形式。

1. 第一种形式,指针变量法:*指针变量

#include<stdio.h>
int main()
{
	int a[10]={1,5,3,8,6,12,90,0,13,5},i,*p;
	int max,min;
	max=min=a[0];
	for(p=a+1;p<a+10;p++)
	{
		if(*p>max)//if(a[i]>max)
			max=*p;//max=a[i];
		if(*p<min)//if(a[i]<min)
			min=*p;//min=a[i]
	}	
	printf("max:%d\nmin:%d\n",max,min);
	return 0;
} 

该形式,需要不断改变指针变量p的指向。
想一下,既然数组名a表示数组的首地址,a+1表示a[1]元素的地址,能否像指针变量p那样,对a执行a++操作呢????

2. 第二种形式,首地址法:*(首地址+偏移量)

#include<stdio.h>
int main()
{
	int a[10]={1,5,3,8,6,12,90,0,13,5},i,*p;
	int max,min;
	max=min=a[0];
	for(p=a,i=1;i<10;i++)
	{
		if(*(p+i)>max)//if(a[i]>max)
			max=*(p+i);//max=a[i];
		if(*(p+i)<min)//if(a[i]<min)
			min=*(p+i);//min=a[i]
	}
	printf("max:%d\nmin:%d\n",max,min);
	return 0;
}

该形式,并未改变指针变量p的指向,语句p=a;使得p指向数组a的首地址,采用p+i的方法来表示a[i]的首地址,进而通过*(p+i)获得a[i]元素的值。

3. 第三种形式,下标法:数组名[下标]

#include<stdio.h>
int main()
{
	int a[10]={1,5,3,8,6,12,90,0,13,5},i,*p;
	int max,min;
	p=a;
	max=min=p[0];
	for(i=1;i<10;i++)
	{
		if(p[i]>max)
			max=p[i];
		if(p[i]<min)
			min=p[i];
	}
	printf("max:%d\nmin:%d\n",max,min);
	return 0;
}

我们知道,a[i]可以表示数组a中下标为i的元素,当把p=a;之后,也可以通过p[i]的形式来描述a[i]元素。

猜你喜欢

转载自blog.csdn.net/lvcongying0601/article/details/84108618