指针

  • 取地址运算

运算符 &

 scanf("%d",&i);里的&,作用是获取变量的地址,它的操作数必须是变量

int i;
printf("%x",&i);

 地址的大小是否与int相同取决于编译器

int i;
printf("%p",&i);

 &不能对没有地址的东西取地址

  eg:&(a+b)、&(a++)、&(++a)

可取

 1)变量的地址

 2)相邻变量的地址

 3)&的结果的sizeof

#include<stdio.h>

int main(void)
{
    int i = 0;
    int p;

    printf("%p\n",&i);
    printf("%p\n",&p);

    return 0;
}

 4)数组的地址

 5)数组单元的地址

 6)相邻的数组单元的地址

#include<stdio.h>

int main(void)
{
    int a[10];

    printf("%p\n",&a);
    printf("%p\n",a);
    printf("%p\n",&a[0]);
    printf("%p\n",&a[1]);

    return 0;
}
  • 指针

 保存地址的变量

int i;
int* p = &i;     //* p 表示p是一个指针,指向int
int* P,q;      //*位置可以靠近int,但q只是一个普通的int类型的变量
int *p,q;      //*位置也可以远离int, · ·
  •  指针变量

 变量的值是内存的地址

  普通变量的值是实际的值

  指针变量的值是具有实际值的变量的地址

  • 作为参数的指针
void f(int *p);   //f需要一个int的指针,在被调用的时候得到了某个变量的地址

int i = 0;
f(&i);    //在函数里面可以通过这个指针访问外面这个i


#includ<stdio.h>

void f(int *p);

int mai(void)
{
    int i = 6;
    printf("&i=%p\n",&i);
    f(&i);

    return 0;
}

void f(int*p)
{
    printf("p=%p\n",p);
}
  • 访问地址上的变量*

 *是一个单目运算符,用来访问指针的值所表示的地址上的变量,可以做右值也可以做左值

  int k = *p;

  *p = k+1;

#include<stdio.h>

void f(int *p);
void g(int k);

int main(void)
{
    int i = 6;
    printf("&i=%p\n",&i);
    f(&i);
    g(i);

    return 0;
}

void f(int *p)
{
    printf(" p=%p\n",p);
    printf("*p=%d\n",*p);   //通过p指针访问到了p所指的int i里面的值
    *p = 26;   //得到k = 26
}

void g(int k)
{
    printf("k=%d\n",k);
}

*左值之所以叫左值,是因为出现在赋值号左边的不是变量,而是值,是表达式计算的结果:a[0] = 2;、*p = 3;是特殊值

  • 指针的运算符&*

 互相反作用

 *&yptr -> * (&yptr) -> *(yptr的地址) -> 得到那个地址上的变量 -> yptr

 &*yptr -> &(*yptr) -> &(y) -> 得到y的地址,也就是yptr -> yptr

  • 传入地址

 

  • 指针的使用

 应用场景一

  交换两个变量的值

#include<stdio.h>

void swap(int *pa, int *pb);

int main(void)
{
    int a = 5;
    int b = 6;
    swap(&a,&b);
    printf("a=%d,b=%d\n",a,b);

    return 0;
}

void swap(int *pa, int *pb);
{
    int t = *pa;
    *pa = *pb;
    *pb = t;
}

 应用场景二

  a、函数返回多个值,某些值就只能通过指针返回,传入的参数实际上是需要保存待会的结果的变量

#include<stdio.h>

void minmax(int a[], int len, int *max, int *min);

int main(void)
{
    int a[] = {1,2,3,4,5,6,7,8,9,12,13,14,16,17,21,23,55,};
    int min,max;
    minmax(a, sizeof(a)/sizeof(a[0]),&min,&max);
    printf("min=%d,max=%d\n",min,max);

    return 0;
}

void minmax(int a[], int len, int *min, int *max)
{
    int i;
    *min = *max = a[0];
    for ( i=1; i<len; i++)
    {
        if( a[i] < *min )
        {
            *min = a[i];
        }
        if( a[i]> *max )
        {
            *max = a[i];
        }
    }
}

  b、函数返回运算的状态,结果通过指针返回。常用套路是让函数返回特殊的不属于有效范围内的值来表示出错:-1或0,但是当任何数值都是有效的可能结果时,就得分开返回,状态用函数的return返回,实际值通过指针参数返回

  • 指针的常见错误

 定义了指针变量,还没有指向任何变量,就开始使用指针

  • 指针与数组

 函数参数表中的数组实际上是指针,sizeof(a) == sizeof(int*),但是可以用数组的运算符[ ]进行运算

  • 数组参数

 以下四种函数原型是等价的:

int sum(int *ar,int n);
int sum(int *,int);
int sum(int ar[],int n);
int sum(int [],int n);

数组变量是特殊的指针

 数组变量本身表达地址,所以

int a[10];
int*p = a;     //无需用&取地址

//但数组的单元表达是变量,需要用&取地址

a == &a[0]

 [ ]运算符可以对数组做,也可以对指针做:

  p[0] <==> a[0]

 *运算符可以对指针做,也可以对数组做:

  *a = 25;

 数组变量时const的指针,所以不能被赋值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值