C语言指针(1)

地址和指针的概念:

      内存区的每一个字节有一个编号,这就是地址。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。

      在C语言中,对变量的访问有两种方式,直接访问和间接访问。

       直接访问如:a=5;

               系统在编译时,已经对变量分配了地址,例如,若变量a分配的地址是2000,则该语句的作用就是把常数5保存到地址为2000的单元。

       间接访问如:scanf("%d",&a);

               调用函数时,把变量a的地址传递给函数scanf,函数首先把该地址保存到一个单元中,然后把从键盘接收的数据通过所存储的地址保存到a变量中。

在C语言中,指针是一种特殊的百年量,它是存放地址的。假设我们定义了一个指针变量int *i_pointer用来存放整型变量i的地址。可以通过语句:i_pointer=&i;

      

      将i的地址(2000)存放到i_pointer中。这时i_pointer的值就是2000,即变量i所占用单元的起始地址。

      要存取变量i的值,可以采用间接方式:先找到存放“i的地址”的变量i_pointer,从中取出i的地址2000,然后取出i的值3。

*:这个符号叫做取值操作符;

&:这个符号叫做取址操作符。

如:

int i=2000;
int *pointer;//这里的*是声明pointer为指针变量的一个特征
pointer=&i;
printf("%d\n",*pointer);//这里的*才是取值操作
打印出的结果应该是2000。

指针与指针变量:

      知道了一个变量的地址,就可以通过这个地址来访问这个变量,因此又把变量的地址称为该变量的指针。
      C语言中可以定义一些特殊的变量,这些变量专门用来存放变量的地址,称为指针变量。

      指针变量中存放的值是指针(即地址)。

定义指针变量:

      指针前面的“*”,表示该变量的类型为指针型变量。其一般形式为:  类型说明符 *变量名;

      在定义指针变量时必须指定基类型。需要注意的是,只有整型变量的地址才能放到指向整型变量的指针变量中。

      指针变量中只能存放地址,不要将一个整数或任何其他非地址类型的数据赋给一个指针变量,否则编译器也会把该值当成一个地址来处理。

C语言中提供了地址运算符&来表示变量的地址。其一般形式为:&变量名;变量本身必须预先声明。

例题:通过指针变量访问整形变量:

#include<stdio.h>
int main()
{
    int a,b;
    int *pointer_1,*pointer_2;
    a=100;
    b=10;
    pointer_1=&a;
    pointer_2=&b;
    printf("%d,%d\n",a,b);
    printf("%d,%d\n",*pointer_1,*pointer_2);
}
对“&”和“*”再做些说明:

      如果已经执行了语句 pointer_1=&a;

   1、&*pointer_1的含义是什么?

         “&”和“*”两个运算符的优先级相同,但按自右向左方向结合,因此先进行*pointer_1的运算,它就是变量a,再执行&运算。因此,&*pointer_1与&a相同,即变量a的地址。

   2、如果有pointer_2=&*pointer_1;

         它的作用是将&a(a的地址)赋给pointer_2,pointer_2就指向了a。

*&a的含义是什么?

      先进行&a运算,得a的地址,再进行*运算。即&a所指向的变量,也就是变量a。

      *&a和*pointer_1的作用是一样的,它们都等价于变量a。即*&a与a等价。

(*pointer_1)++相当于a++。

      注意括号是必要的,如果没有括号,++和*为同一优先级,结合方式自右向左,就变成了*(poiinter_1++)。

例题:输入a和b两个整数,按从大到小的顺序输出a和b。

           代码有些多此一举,不过是要明白指针的基本用法。

#include<stdio.h>
int main()
{
    int *p1,*p2,*p,a,b;
    scanf("%d%d",&a,&b);
    p1=&a;
    p2=&b;
    if(a<b)
    {
        p=p1;
        p1=p2;
        p2=p;
    }
    printf("a=%d,b=%d\n",a,b);
    printf("max=%d,min=%d\n",*p1,*p2);
}
           

       下面这个代码依旧是上面的题,但是是将指针变量作为函数的参数实现:

#include<stdio.h>
void swap(int *p1,int *p2);
int main()
{
    int a,b;
    int *pointer_1,*pointer_2;
    scanf("%d%d",&a,&b);
    pointer_1=&a;
    pointer_2=&b;
    if(a<b)
    {
        swap(pointer_1,pointer_2);//swap实现的是交换
    }
    printf("\n%d > %d\n",a,b);
}
void swap(int *p1,int *p2)
{
    int temp;
    temp=*p1;
    *p1=*p2;
    *p2=temp;
}


例题:输入a,b,c,三个数,将它们从大到小输出。

#include<stdio.h>
int main()
{
    void exchange(int *q1,int *q2,int *q3);
    int a,b,c,*p1,*p2,*p3;
    scanf("%d%d%d",&a,&b,&c);
    p1=&a;
    p2=&b;
    p3=&c;
    exchange(p1,p2,p3);
    printf("\n%d>%d>%d\n",a,b,c);
}
void exchange(int *q1,int *q2,int *q3)
{
    void swap(int *pt1,int *pt2);
    if(*q1<*q2)
    {
        swap(q1,q2);
    }
     if(*q1<*q3)
    {
        swap(q1,q3);
    }
    if(*q2<*q3)
    {
        swap(q2,q3);
    }

}
void swap(int *pt1,int *pt2)
{
    int temp;
    temp=*pt1;
    *pt1=*pt2;
    *pt2=temp;
}


数组与指针:

      一个变量有地址,一个数组包含若干个元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量不仅可以指向变量,也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元素的地址。

例题:假设有一个a数组,整型,有10个元素。要输出各元素的值有三种方法:

            1、下标法;

            2、通过数组名计算数组元素地址,找出元素的值;

            3、用指针变量指向数组元素。

第一种:

#include<stdio.h>
int main()
{
    int a[10];
    int i;
    for(i=0;i<10;i++)
    {
        scanf("%d",&a[i]);
    }
    printf("\n");
    for(i=0;i<10;i++)
    {
        printf("%d ",a[i]);
    }
}
第二种:

#include<stdio.h>
int main()
{
    int a[10];
    int i;
    for(i=0;i<10;i++)
    {
        scanf("%d",&a[i]);
    }
    printf("\n");
    for(i=0;i<10;i++)
    {
        printf("%d ",*(a+i));//这里a是首地址,i表示偏移,*表示取值
    }
}
第三种:

#include<stdio.h>
int main()
{
    int a[10];
    int i;
    int *p;
    for(i=0;i<10;i++)
    {
        scanf("%d",&a[i]);
    }
    printf("\n");
    for(p=a;p<(a+10);p++)
    {
        printf("%d ",*p);
    }
}


f(int arr[ ],int n)相当于f(int *arr,int n)

需要说明的是:C语言调用函数时虚实结合的方法都是采用“值传递”的方式,当变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参为指针变量。

例题:将数组a中n个整数按相反顺序存放。如图所示:


第一个版本,用数组名做参数:

#include<stdio.h>
void reverse(int x[],int n);
int main()
{
    int i,a[10]={3,7,9,11,0,6,7,5,4,2};
    printf("The original array:\n");
    for(i=0;i<10;i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
    reverse(a,10);
    printf("The array has been inverted:\n");
    for(i=0;i<10;i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
}
void reverse(int x[],int n)
{
    int temp,i,j,m;
    m=(n-1)/2;
    for(i=0;i<=m;i++)
    {
        j=n-1-i;
        temp=x[i];
        x[i]=x[j];
        x[j]=temp;
    }
}

第二个版本,用指针做函数参数:

#include<stdio.h>
void reverse(int *x,int n);
int main()
{
    int i,a[10]={3,7,9,11,0,6,7,5,4,2};
    printf("The original array:\n");
    for(i=0;i<10;i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
    reverse(a,10);
    printf("The array has been inverted:\n");
    for(i=0;i<10;i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
}
void reverse(int *x,int n)
{
    int *p,temp,*i,*j,m;
    m=(n-1)/2;
    i=x;       //i指向的是数组的第一个元素
    j=x+n-1;   //j指向的是数组的最后一个元素
    p=x+m;     //p指向中间,配对
    for( ;i<=p;i++,j--)
    {
        temp=*i;
        *i=*j;
        *j=temp;
    }
}

例题:从10个数中找出其中的最大值和最小值。

#include<stdio.h>
int max,min;
void max_min_value(int array[],int n);
int main()
{
    int i,number[10];
    printf("enter 10 integer numbers:\n");
    for(i=0;i<10;i++)
    {
        scanf("%d",&number[i]);
    }
    max_min_value(number,10);
    printf("\nmax=%d,min=%d\n",max,min);
}
void max_min_value(int array[],int n)
{
    int *p,*array_end;
    array_end=array+n;
    max=min=*array;
    for(p=array+1;p<array_end;p++)
    {
        if(*p>max)
        {
            max= *p;
        }
        else if(*p<min)
        {
            min=*p;
        }
    }
}

例题:将给定的10个数从大到小输出。

#include<stdio.h>
void sort(int x[],int n);
int main()
{
    int *p,i,a[10]={3,7,9,11,0,6,7,5,4,2};
    printf("The original array:\n");
    for(i=0;i<10;i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
    p=a;
    sort(p,10);
    printf("The result is:\n");
    for(i=0;i<10;i++)
    {
        printf("%d ",*p);
        p++;
    }
    printf("\n");
}
void sort(int x[],int n)
{
    int i,j,k,t;
    for(i=0;i<n-1;i++)
    {
        for(j=i+1;j<n;j++)
        {
            if(x[j]>x[i])
            {
                t=x[j];
                x[j]=x[i];
                x[i]=t;
            }
        }
    }
}





      

      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值