C语言基础——指针1


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;


3.指针变量未经过初始化,不要拿来间接访问其他存储空间

 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后会有如下结果:

1a[0],*(a+0),*a表示00列元素地址。

2a+1,&a[1]表示1行首地址。

3a[1],*(a+1)表示10列元素a[1][0]的地址。

4a[1]+2*a+1)+2,&a[1][2]代表12列元素a[1][2]的地址。

5*(a[1]+2),*(*(a+1)+2),a[1][2]代表12列元素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;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值