#学习笔记 C语言指针

讲解视频:
https://www.bilibili.com/video/av19474068/?spm_id_from=333.788.videocard.1
https://www.bilibili.com/video/av9855378

在实验楼学习

1.引用指针变量

  • 给指针变量赋值
    p=&a; //把a的地址赋给指针变量p
  • 引用指针变量指向的变量
如果已经执行 p=&a; 即指针变量 p 指向了整形变量 a,则
printf("%d",*p);

把 1 赋给 a

*p=1;

把p的地址改成1

p=1
  • 引用指针变量的值
printf("%o",p);

作用是以八进制数形式输出指针变量 p 的值,如果 p 指向了 a,就是输出了 a 的地址,即 &a。

例子:
输入两个整数,按先大后小的顺序输出 a 和 b。

解题思路:用指针的方法来处理这个问题。不交换整形变量的值,而是交换两个指针变量的值。


    #include<stdio.h>
int main()
{
    int *p1,*p2,*p,a,b;

    printf("please enter two integer number:");
    scanf("%d,%d",&a,&b);
    p1 = &a;
    p2 = &b;
    if(a<b)
    {
        p = p1;
        p1 = p2;
        p2 = p;          //使p1和p2的值互换
    }

    printf("a=%d,b=%d\n",a,b);
    printf("max=%d,min=%d\n",*p1,*p2);

    return 0;
}

例子:
将上面的例子使用函数来实现

#include<stdio.h>
int main()
{
    void swap(int * point_1,int * point_2);
    int *p1,*p2,a,b;

    printf("please enter two integer number:");
    scanf("%d %d",&a,&b);
    p1 = &a;
    p2 = &b;
    if(a<b)
    swap(p1,p2);  

    printf("max=%d,min=%d\n",a,b);

    return 0;
}

void swap(int * point_1,int * point_2)
{
    int temp;

    temp = * point_1;                 //使*p1和*p2互换
    *point_1 = * point_2;
    *point_2 = temp;
}

需要注意的是,如果使用函数,

void swap(int x ,int y)
{
    int temp;
    temp = x;
    x = y;
    y = temp;
}

是不能够实现的。因为运行完这个函数以后,值就被销毁了。第二个视频也有说这个问题。

例子:
输入 3 个整数 a,b,c 要求按从大到小的顺序将他们输出,用函数实现。

解题思路:

采用 10-3.c 的方法在函数中改变 3 个变量的值。用 swap 函数交换两个变量的值,用 exchange 函数改变着 3 个变量的值。

#include<stdio.h>
int main()
{
    void exchange(int * q1,int * q2,int * q3);
    int a,b,c,*p1,*p2,*p3;

    printf("please enter 3 integer number:");
    scanf("%d%d%d",&a,&b,&c);
    p1 = &a;
    p2 = &b;
    p3 = &c;
    exchange(p1,p2,p3);

    printf("the order is :%d,%d,%d\n",a,b,c);

    return 0;
}

void exchange(int *q1,int *q2,int *q3)
{
    void swap(int *p1,int *p2);
    if(* q1<* q2) swap(q1,q2);
    if(* q1<* q3) swap(q1,q3);
    if(* q2<* q3) swap(q2,q3);
}

void swap(int *p1,int *p2)
{
    int temp;

    temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}

2.通过指针来引用数组

int a[10]={1,2,3,4,5,6,7,8,9,10};
int *P;
p = &a[0];

注意,

p = &a[0];和 p = a;等价
因为p = a 指向的是数组a的第0个元素
(p+1)指的是a[1],亦可写作
*(p+1)=a[1];

同时,
a[0]也和*a
a[1]也和*(a+1)
等价

例子
三种表示数组的方法:
1

#include<stdio.h>
int main()
{
    int a[10];
    int i;

    printf("please enter 10 integer numbers: ");
    for(i=0;i<10;i++)
        scanf("%d",&a[i]);

    for(i=0;i<10;i++)
        printf("%d\t",a[i]);     //数组元素用数组名和下标表示

    return 0;
}

2

#include<stdio.h>
int main()
{
    int a[10];
    int i;

    printf("please enter 10 integer numbers: ");
    for(i=0;i<10;i++)
        scanf("%d",&a[i]);

    for(i=0;i<10;i++)
        printf("%d\t",*(a+i));  //通过数组名和元素序号计算元素地址,再找该元素

    return 0;    
}

3

#include<stdio.h>
int main()
{
    int a[10];
    int *p,i;

    printf("please enter 10 integer numbers: ");
    for(i=0;i<10;i++)
        scanf("%d",&a[i]);

    for(p=a;p<(a+10);p++)
        printf("%d\t",*p);  //用指针指向当前的数组元素

    return 0;  
}

第 1 种和第 2 种方法的执行效率是相同的。C 编译系统是将 a[i] 装换为 *(a+i) 处理的,即先计算元素的地址。因此用第 1 和第 2 种方法找数组元素费时较多。

第 3 种方法比第 1、第 2 种方法快,用指针变量直接指向元素,不必每次都重新计算地址,像 p++ 这样的自加操作是比较快的。这种有规律的改变地址值 p++ 能大大提高执行效率。

用下标比较直观,能直接知道是第几个元素。例如,a[5] 是数组中序号为 5 的元素(注意序号是从 0 算起)。用地址发或者指针变量的方法不直观,难以很快的判断出当前处理的是哪一个元素。例如,方法 3 中,要仔细分析指针变量 p 的当前指向,才能判断当前输出的是第几个元素。有经验的程序猿往往喜欢用第 3 种形式,用 p++进行控制,程序简洁、高效。对于小白用户最好还是用第 1 种方式,直观,不易出错。

但是,需要注意的是,这个替换是不可以的

for(p=a;p<(a+10);p++)
    printf("%d\t",*p);
for(p=a;a<(p+10);a++)
    printf("%d",*a);

因为a是常量而不是变量,a++不合法。

例子:
将输入进来的序列,反着输出出去

解题思路:将 a[0] 与 a[n-1] 对换,再将 a[1] 和 a[n-2] 对换…直到将 a[int (n-1)/2] 与 a[n-int(n-1)/2-1] 对换。现用循环处理此问题,设两个“位置指示变量” i 和 j,i 的初的 0,j 的初值为 n-1。将 a[i] 和 a[j] 交换,然后是 i 的值加1,j 的值减 1,再将 a[i] 和 a[j] 交换,直到 i=(n-1)/2 为止。

用一个函数 change 来实现交换。实参用数组名 a,形参可用数组名,也可用指针变量名。

方法1

#include<stdio.h>
int main()
{
    void change(int x[],int n);
    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\t",a[i]);
    printf("\n");

    change(a,10);
    printf("the array has been inverted:\n");
    for(i=0;i<10;i++)
        printf("%d\t",a[i]);

    return 0;
}

void change(int x[],int n)
{
    int temp,i,j,m=(n-1)/2;

    for(i=0;i<=m;i++)
    {
        j = n - 1 - i;
        temp = x[i];
        x[i] = x[j];
        x[j] = temp;
    }
}

方法2

#include<stdio.h>
int main()
{
    void change(int *x,int n);
    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\t",a[i]);
    printf("\n");

    change(a,10);
    printf("the array has been inverted:\n");
    for(i=0;i<10;i++)
        printf("%d\t",a[i]);

   return 0;
}

void change(int *x,int n)
{
    int *p,temp,*i,*j,m = (n-1) / 2;

    i=x;j=x+n-1;p=x+m;
    for(;i<=p;i++,j--)
    {
        temp = *i;
        *i = *j;
        *j = temp;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值