1. 指针是什么
如果在程序中定义一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。内存区的每一个字节有一个编号,这就是地址。通过地址可以找到所需变量单元,可以说,地址指向该变量单元。因此,将地址形象化地称为“指针”,意思是通过它能找到以它为地址的内存单元。
2. 怎样定义指针变量
类型名 *指针变量名
例如:
int * pointer_1 ,*pointer_2</span>
左端的int是在定义指针变量时必须指定的基类型。指针变量的基类型用来指定此指针变量可以指向的变量的类型。
注意:1、在定义时指针变量名前的*代表该变量的类型为指针型,并非指针变量名为“*pointer”。2、必须指定“基类型”。
怎样引用指针变量
在应用指针变量时,可能有3种情况。
1、给指针变量赋值。如,p= & a ; //把a的地址赋给指针变量
2、引用指针变量指向的变量。
如果已执行“p = & a ;” 即指针变量p指向了整形变量a,则 printf("%d", *p);
3、引用指针变量的值,如printf (“ &o ,p”)
例如,通过指针变量访问整形变量。
#include <stdio.h>
int main ()
{
int a = 100 , b =10 ;
int *pointer_1 , *pointer_2;
pointer_1 = & a ;
pointer_2 = &b ;
printf (“%d,%d”,*pointer_1,pointer_2);
return 0 ;
}
</span>
指针的使用注意
1.不建议的写法, int *p只能指向int类型的数据int *p;
int *p;
double d = 10.0;
p = &d;
2.指针变量只能存储地址
int *p;
p = 200;
int *p;
printf("%d\n", *p);
4.定义变量时的*仅仅是一个象征,没有其他特殊含义
int *p = &a;
5.不正确的写法
*p =&a;
p = &a;
6.这个时候的*的作用:访问指向变量p指向的存储空间
*p = 20;
3.指针变量作为函数参数
函数的参数不仅可以是整型、浮点型、字符型等数据,还可以使指针类型。它的作用是将一个变量的地址传送到另一个函数中。
例如,使用指针变量对两数进行排序
#include <stdio.h>
int main()
{
void swap(int *p1,int *p2);
int a,b;
printf("Please input 2 integer: ");
scanf("%d%d",&a,&b);
if(a<b)
{
int *p1=&a,*p2=&b;
swap(p1,p2);//变量只能进行值传递,指针变量可以进行地址传递
}
printf("max_a=%d, min_b=%d\n",a,b);
return 0;
}
void swap(int *p1,int *p2)
{
int temp;
temp=*p1;
*p1=*p2;//注意:p2是形参,且仅代表指向b指针,交换指针变量的值并不对b的值造成任何影响
*p2=temp;//指针运算符使temp直接对指针所指向的值进行赋值
}
4.通过指针引用数组
数组元素的指针
一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素。所谓数组元素的指针就是数组元素的地址。
数组名代表数组首元素的地址,例如,
pointer=&a[0]; 或 pointer=a;) 效果相同,代表将数组首元素地址赋值到指针变量pointer。
在引用数组元素时指针的运算
在指针指向数组元素时,可以对指针进行以下运算:
加一个整数,如p+1;
减一个整数,如p-1;
自加运算,如p++,++p;
自减预算,如p--,--p;
如果指针变量p已指向数组中的一个元素,则pointer+1指向同一数组中的下一个元素,pointer-1指向同一数组中的上一个元素。pointer+1实际上代表(pointer+1)*d,d是一个数组元素所占的字节数(比如Visual C++中float是4)。
通过指针引用数组元素
引用数组元素,可以使用的两种方法:
1、下标法,如a[i]形式。
2、指针法,如*(a+i)形式。其中a是数组名,p是指向数组元素的指针变量,其初值p=a。
例如,用指针变量对数组进行赋值并遍历
#include <stdio.h>
int main()
{
int i,a[5],*p=a;
printf("Please input 5 integer number:\n");
for(i=0;i<5;i++)
{
scanf("%d",p++);//scanf函数本身对地址指向的存储单元进行赋值,因此不需要*p
}
p=a;//经过上述循环后p指向a[4]元素地址,因此需要重新指向a[0]
for(i=0;i<5;i++,p++)
{
printf("a[%d]=%d ",i,*p);
}
printf("\n");
return 0;
}
用指针引用多维数组
假设有一个二维数组a,那么printf后会有如下结果:
1、a[0],*(a+0),*a表示0行0列元素地址。
2、a+1,&a[1]表示1行首地址。
3、a[1],*(a+1)表示1行0列元素a[1][0]的地址。
4、a[1]+2,*(a+1)+2,&a[1][2]代表1行2列元素a[1][2]的地址。
5、*(a[1]+2),*(*(a+1)+2),a[1][2]代表1行2列元素a[1][2]的值。
注意:二维数组名是指向行的,因此a+1中的1代表一行中全部元素所占的字节数,一维数组名师指向列元素的。不要把&a[i]简单地理解为a[i]元素的物理地址,因为并不存在a[i]这样一个实际的数据存储单元。它只是一种地址的计算方法,能得到第i行的首地址。&a[i]和a[i]值相等,即它们代表同一地址,但它们所指向的对象是不同的,即指针的基类型是不同的。
例如,输出二维数组有关数据
#include <stdio.h>
int main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
printf("%d, %d\n",a,*a);
printf("%d, %d\n",&a[0],&a[0][0]);
printf("%d, %d\n",a[1],a+1);
printf("%d, %d\n",&a[1][0],*(a+1)+0);
printf("%d, %d\n",a[2],*(a+2));//*(a+2)只是a[2]的另一种表现形式
printf("%d, %d\n",&a[2],a+2);
printf("%d, %d\n",a[1][0],*(*(a+1)+0));
printf("%d, %d\n",*a[2],*(*(a+2)+0));
int *p;
for(p=a[0];p<a[0]+12;p++)
{
if((p-a[0])%4==0) printf("\n");
printf("%4d",*p);
}
printf("\n");
return 0;
}