1.指针是什么
(1)概念
指针是一种十分重要的数据类型,利用指针变量可以直接对内存中各种不同数据结构的数据进行 快速处理.
(2)指针与内存的关系
指针与内存有着密切的联系,为了正确理解指针的概念,必须弄清楚计算机系统中数
据存储和读取的方式。首先需要区分三个较为相近的概念:名称、地址和内容(值))。名称
是给内存空间取的一个容易记忆的名字:内存中每个字节都有一个编号,这就是“地址“,在地址所对应的内存单元中存放的数值即为内容或值。在计算机中,所有的数据都是存放
在存储器中的。一般把存储器中的一个字节称为一个内存单元,不同的数据类型质占用的
内存单元数不等,若在程序中定义了变量,在对程序进行编译时,系统就会为这些变量分
配与变量类型相符合的相应长度空间的内存单元。
例如:
Visual C++ 6.0 和 C-Free3.5 中:
int型指针 :4个字节
char型指针:1个字节
double型指针:8个字节
short int 型指针:2个字节
(2)访问方式
1.间接访问:将变量的地址存放在一种特殊的变量中(我们这里讲的指针),借用这个特殊变量进行访问。
2.直接访问:用变量明对变量进行访问的方式为直接访问的方式,也可称作按变量地址直接存取的方式。
2.指针的定义和初始化
1.定义:
定义格式为:类型说明符*变量名
例如:int*p;char*p;double*p;
其中:p是一个指针变量,它的值是个地址,int*表示p是一个整型类型的指针,在这里*是一个类型说明符。
2.初始化
初始化包括定义和赋值
初始化的方式:
(1)int a;
int*p=&a;
(2)int a; int*p;
p=&a;
注意:不能直接把一个数赋予指针变量,如:int*p;p=100;是错误的。
被赋值的指针变量前不能再加 * 说明符,如:*p=&a;是错误的.
(3)区分int*p和printf("%d",*p);中的*,前者*是类型说明符,后者是取值运算符,表示p这个地址里面存储的值。
3.运算符的优先级和有关指针的计算和应用
(1)优先级
1.首先取地址符&和取值运算符*的优先级是一样的,并且结合性都是自右向左,
所以 假设有&a,且int*p;p=&a;则 &(*p)=&*p=&a
2.++和*的优先级相同,结合方向都是自右向左
所以*p++和*(p++)是等价的,由于++在p的右侧,是先使用后加一,因此先对p原值进行*运算,
然后改变p的值。
(2)有关指针的计算和应用
1.通过指针变量求两个整数的和与积
#include<stdio.h>
int main()
{
int a=10,b=20,s,j,*pa,*pb;
pa=&a;
pb=&b;
s=*pa+*pb;
j=*pa**pb;
printf("a=%d\nb=%d\na+b=%d\na*b=%d\n",a,b,a+b,a*b);
printf("s=%d\nj=%d\n",s,j);
return 0;
}
程序中第 3 行定义了两个整型指针变量 pa 和 pb;第 4、5 行分别给指针变量 pa赋变
量 a的地址,给指针变量 pb 赋变量 b 的地址;第 6 行是求 a+b(*pa就是 a,*pb 就是 b);
第7 行求 a×b,第8行和第 9行输出 a+b 和 a×b的结果。
2.通过指针变量求三个整型数中的最大数和最小数
#include<stdio.h>
int main()
{
int a,b,c,*max,*min;
printf("请输入三个整数:");
scanf("%d%d%d",&a,&b,&c);
if(a>b)
{
max=&a;
min=&b;
}
else
{
max=&b;
min=&a;
if(c>*max)max=&c;
if(c<*min)min=&c;
printf("max=%d\nmin=%d\n",*max,*min);
}
return 0;
}
程序中第 3 行定义了两个整型指针变量 max 和 nint第 4.行为输入提示;第5行输入
3个数字,接着判断前两个数的大小,在 max 变量中存放较大数的地址,min变量中存放
较小数的地址;然后再将第 3个数与以上较大数和较小数进行比较,从而得到3个数中的
最大数和最小数并将其输出。
(3)指针变量作为函数的参数
题目:输入a和b两个整数,按照先后大小的顺序输出。
#include<stdio.h>
void arr(int*pa,int*pb)//定义一个函数arr使a为最大值
{
int t;
t=*pa;
*pa=*pb;
*pb=t;
}
int main()
{
int a,b;
int *pa,*pb;
pa=&a;
pb=&b;
scanf("%d,%d",pa,pb);//接收数字,将数字存放到地址pa,pb中
if(a<b)
arr(pa,pb);
printf("%d,%d",a,b);
return 0;
}
4.指针和普通数组的联系
(1)数组的地址
数组的地址指的是数组的起始地址,这个起始地址也称为数组的指针。
数组的起始地址=数组名=数组的首元素的地址。
例如:
int arr[5]={1,2,3,4,5},*p;
在这里*p=arr和*p=&arr[0]是等价的
(2)访问数组的方式
1.用下标法访问数组
#include<stdio.h>
int main()
{
int arr[5],i;
printf("请输入5个整数:");
for(i=0;i<5;i++)
scanf("%d",&arr[i]);
for(i=0;i<5;i++)
printf("%d\n",arr[i]);
return 0;
}
2.用数组名访问数组
#include<stdio.h>
int main()
{
int arr[5],i;
printf("请输入5个整数:");
for(i=0;i<5;i++)
scanf("%d",&arr[i]);
for(i=0;i<5;i++)
printf("%d\n",*(arr+i));
return 0;
}
3.用指针变量访问数组
#include<stdio.h>
int main()
{
int arr[5],i;
int*p=arr;
printf("请输入5个整数:");
for(i=0;i<5;i++)
scanf("%d",&arr[i]);
for(i=0;i<5;i++)
printf("%d\n",*(p+i));
return 0;
}
由此可见上面三种访问方式的运行结果都是一样的,所以数组和指针是密切相关的。
注意:第三个例子中*(p+1)中的p+1并不是简单的将地址加1,而是指向数组的下一个元素,
而地址的变化要根据数组的类型来确定,比如int型数组每个元素相差4个字节,而char型每个元素相差一个字节。
(3)利用指针来定义一个数组
有时候我们也可以利用指针来定义一个数组
例如:利用字符型指针定义一个字符型数组
#include<stdio.h>
#include<string.h>
int main()
{
char*str="i like studying";
int i,length;
length=strlen(str);
for(i=0;i<length;i++)
{
printf("%c\n",str[i]);
}
return 0;
}
5.指针数组
1.定义
指针数组是一个用来存放指针变量的数组
一般形式为:类型* 数组名[元素个数],如下
int*arr[5];
int*代表它是一个存放int型指针变量的数组,arr是数组名,arr[5]代表arr数组里有5个int型指针变量.
2.初始化
我们这里举个简单的例子来说明
#include<stdio.h>
int main()
{
int a=1,b=2,c=3;
int*p[3]={&a,&b,&c};//指针数组的初始化
int i;
for(i=0;i<3;i++)
{
printf("%d\n",*p[i]);
}
return 0;
}
注意:指针数组必须存放的是指针变量,不能是数字或者字母。
3.有关指针数组的题目
题目:用一个函数计算有n个元素的指针数组s中最长的字符串的长度。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int max_len(char*s[],int n)
{
int i;
int max;
max=strlen(s[0]);//先设最长的字符串就是指针数组的第一个元素
for(i=0;i<n;i++)//用循环逐一和max比较选出最长的元素
{
if(strlen(s[i])>=max)
max=strlen(s[i]);}
return max;//返回最长字符串的长度
}
int main()
{
int max,n,m,p;
printf("输入字符串的个数:");
scanf("%d",&n);
printf("请输入%d个字符串:",n);
char*s[p]={NULL};
for(m=0;m<n;m++)//利用循环给指针数组赋值
{
s[m]=(char*)malloc(sizeof(char)*p);//开辟动态内存空间
scanf("%s",s[m]);
}
max=max_len(s,n);
printf("%d\n",max);
return 0;
}
温馨提示:这里所讲的内容只是指针中的基本部分,指针还有许多知识点。还有如果有错误的地方,欢迎各位大神留言喔,大家一起学习进步吧。