一个变量的地址称为该变量的指针。
如果有一个变量专门用来存放另一个变量的地址,它就是指针变量。
1、指针基础示例
从键盘中输入两个数,利用指针的方法将这两个数输出
#include<stdio.h>
int main()
{
int a, b;
int *ipointer1,*ipointer2; /*声明两个指针变量*/
scanf("%d,%d",&a,&b); /*输入两个数*/
ipointer1 = &a;
ipointer2 = &b; /*将地址赋给指针变量*/
printf("The number is:%d,%d\n",*ipointer1,*ipointer2);
return 0;
}
输出结果:
2、指针自加自减运算
#include<stdio.h>
int main()
{
int i;
int *p;
printf("please input the number:\n");
scanf("%d",&i);
p=&i; /*将变量i的地址赋给指针变量*/
printf("the result1 is: %d\n",p);
p++; /*地址加1,这里的1并不代表一个字节*/
printf("the result2 is: %d\n",p);
return 0;
}
输出结果:
结果分析:
基本整型变量 i 在内存中占4个字节,指针 p 是指向变量 i 的地址的,这里的 p++ 不是简单地在地址上加 1,而是指向下一个存放基本整型数的地址。
指针都按照它所指向的数据类型的直接长度进行增或减。
3、一维数组与指针
输出一维数组中的元素
#include<stdio.h>
int main()
{
int *p,*q,a[5],b[5],i;
p=&a[0];
q=b;
printf("please input array a:\n");
for(i=0;i<5;i++)
scanf("%d",&a[i]); /*为数组a中的元素赋初值*/
printf("please input array b:\n");
for(i=0;i<5;i++)
scanf("%d",&b[i]); /*为数组b中的元素赋初值*/
printf("array a is:\n");
for(i=0;i<5;i++)
printf("%5d",*(p+i)); /*输出数组a中的元素*/
printf("\n");
printf("array b is:\n");
for(i=0;i<5;i++)
printf("%5d",*(q+i)); /*输出数组b中的元素*/
printf("\n");
return 0;
}
输出结果:
结果分析:
p=&a[0];
q=b;
这两种表示方法都是将数组首地址赋给指针变量。效果相同
上述代码也可改成下面的表达方式:
#include<stdio.h>
int main()
{
int *p,*q,a[5],b[5],i;
p=&a[0];
q=b;
printf("please input array a:\n");
for(i=0;i<5;i++)
scanf("%d",&a[i]); /*为数组a中的元素赋初值*/
printf("please input array b:\n");
for(i=0;i<5;i++)
scanf("%d",&b[i]); /*为数组b中的元素赋初值*/
printf("array a is:\n");
for(i=0;i<5;i++)
printf("%5d",*(a+i)); /*输出数组a中的元素*/
printf("\n");
printf("array b is:\n");
for(i=0;i<5;i++)
printf("%5d",*(b+i)); /*输出数组b中的元素*/
printf("\n");
return 0;
}
输出结果:
输出结果和上面一样。
4、二维数组与指针
利用指针输出二维数组中的元素
#include<stdio.h>
int main()
{
int a[3][5],i,j;
printf("please input:\n");
for(i=0;i<3;i++) /*控制二维数组的行数*/
{
for(j=0;j<5;j++) /*控制二维数组的列数*/
{
scanf("%d",a[i]+j); /*给二维数组元素赋初值*/
}
}
printf("the array is:\n");
for(i=0;i<3;i++)
{
for(j=0;j<5;j++)
{
printf("%5d",*(a[i]+j)); /*输出数组中元素*/
}
printf("\n");
}
return 0;
}
输出结果:
5、字符串与指针
示例1:
#include<stdio.h>
int main()
{
char *string="hello mingri";
printf("%s",string);
return 0;
}
输出结果:
示例2:输出12个月
#include<stdio.h>
int main()
{
int i;
char *month[]=
{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
}; /*给指针数组中的元素赋初值*/
for(i=0;i<12;i++)
printf("%s\n",month[i]);
return 0;
}
输出结果:
6、指向指针的指针
示例:利用指向指针的指针输出一维数组中是偶数的元素,并统计偶数的个数。
#include<stdio.h>
int main()
{
int a[10],*p1,**p2,i,n=0; /*定义数组、指针、变量等为基本整型*/
printf("please input:\n");
for(i=0;i<10;i++)
scanf("%d",&a[i]); /*给数组a中各元素赋值*/
p1=a; /*将数组a的首地址赋给p1*/
p2=&p1; /*将指针p1的地址赋给p2*/
printf("the array is:");
for(i=0;i<10;i++)
{
if(*(*p2+i)%2==0)
{
printf("%5d",*(*p2+i)); /*输出数组中的元素*/
n++;
}
}
printf("\n");
printf("the number is:%d\n",n);
return 0;
}
输出结果:
7、指针变量作函数参数
示例:调用自定义函数交换两个变量的值
#include<stdio.h>
void swap(int *a,int *b)
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
int main()
{
int x,y;
int *p_x,*p_y;
printf("Please enter two numbers:\n");
scanf("%d",&x);
scanf("%d",&y);
p_x=&x;
p_y=&y;
swap(p_x,p_y);
printf("x=%d\n",x);
printf("y=%d\n",y);
return 0;
}
输出结果:
如果上述程序不使用指针,我们看一下效果如何:
#include<stdio.h>
void swap(int a,int b)
{
int tmp;
tmp=a;
a=b;
b=tmp;
}
int main()
{
int x,y;
printf("Please enter two numbers:\n");
scanf("%d",&x);
scanf("%d",&y);
swap(x,y);
printf("x=%d\n",x);
printf("y=%d\n",y);
return 0;
}
输出结果:
我们发现程序并没有交换x和y的值。这是因为在函数调用过程中,主调用函数与被调用函数之间有一个数值传递过程。函数调用中发生的数据传递是单向的,只能把实参的值传递给形参,在函数调用过程中,形参的值发生改变,实参的值不会发生变化,因此上面的这段代码同样不能实现x和y值的互换。
通过指针传递参数可以减少值传递带来的开销,也可以使函数调用不产生值传递。
8、指针函数
返回指针值的函数简称为指针函数。
示例:使用指针函数计算长方形周长
#include<stdio.h>
int Perimeter;
int *per(int a,int b)
{
int *p;
p=&Perimeter;
Perimeter=(a+b)*2;
return p;
}
int main()
{
int iWidth,iLength;
int *iResult;
printf("Please enter the length of the rectangle:\n");
scanf("%d",&iLength);
printf("Please enter the width of the rectangle:\n");
scanf("%d",&iWidth);
iResult=per(iWidth,iLength);
printf("The circumference of the rectangle is:");
printf("%d\n",*iResult);
return 0;
}
结果输出:
注意,这个程序本身不要如此麻烦。可以有更简单的写法,只是用来演示。