栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言指针(2)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言指针(2)

C语言指针(2)
  • 指针的使用
  • 传入函数得数组组成了什么
  • 指针与const
  • 指针运算
  • 指针的类型
  • 动态内存分配

指针的使用
  • 指针能做什么
    • 需要传入较大的数据时用作参数
    • 传入数组后对数组做操作
    • 函数返回不止一个结果
    • 用函数来修改不止一个变量
    • 动态申请的内存

应用场景

  • 应用场景一

    • 交换两个变量
    #include 
    
    void swap(int *pa, int *pb);
    
    int main(void)
    {
        int a = 5;
        int b = 6;
        swap(&a, &b);
        printf("a=%d,b=%d", a, b);
    
        return 0;
    }
    
    void swap(int *pa, int *pb)
    {
        int t = *pa;
        *pa = *pb;
        *pb = t;
    }
    
  • 应用场景二

    • 函数返回多个值,某些值就只能通过指针返回
    • 传入的参数实际上是需要保存带回的
#include 

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

int main(void)
{
    int a[] = {1,14, 65,265,262,3232,8,2,4,561,5,};
    int min, max;
    minmax(a, sizeof(a) / sizeof(a[0]), &min, &max);
    printf("min=%d,max=%dn", min, max);

    return 0;
}

void minmax(int a[], int len, int *min, int *max)
{
    int i = 0;
    *min = *max = a[0];
    for (int i = 1; i < len; i++)
    {
        if (a[i] < *min)
        {
            *min = a[i];
        }
        if (a[i] > *max)
        {
            *max = a[i];
        }
    }
}
  • 应用场景二b

    • 函数返回运算的状态,结果通过指针返回
    • 常用的套路是让函数返回特殊得不属于有效范围内得值来表示出错,但是当任何数值都是有效得可能结果时就得分开返回了
    • 后续的语言(C++、Java)采用异常机制来解决这个问题
    #include 
    
    
    int devide(int a, int b, int *result);
    
    int main(void)
    {
        int a = 5;
        int b = 2;
        int c;
        if (devide(a, b, &c))
        {
            printf("%d/%d=%dn", a, b, c);
        }
    
        return 0;
    }
    
    int devide(int a, int b, int *result)
    {
        int ret = 1;
        if (b == 0)
        {
            ret = 0;
        }
        else
        {
            *result = a / b;
        }
        return ret;
    }
    
传入函数得数组组成了什么
  • 函数参数表中的数组实际上是指针
    sizeof(a)==sizeof(int*)
    -但是可以用数组的运算符[]经行运算
指针与const
  • 指针不可修改 const在*后
  • 不可通过指针修改 const在*前
    const int* p1 = &i; //不能通过指针修改
    int const* p2 = &i; 不能通过指针修改
    int *const p3 = &i; 指针不能被修改
    
  • 转换
    • 总是可以把一个非const的值转换成const的
    • 当要传递的参数的类型比地址大的时候,这是常用的手段:既能用比较少的字节数传递给参数,又能避免函数对外面的变量的修改
  • const数组
    • const int a[] ={1,2,3,4,5,6};
    • 数组变量已经是const的指针,这里的const表明数组的每个单元都是const int
    • 所以必须通过初始化经行赋值
    • const数组可以用于保护数组值:因为把数组传入函数时传递的是地址,所以那个函数内部可以修改数组的值,为了保护数组不被函数修改,可以设置参数为const。
    int sum(const int a[],int length);
    
  • 常见错误:定义了指针变量,还没有指向任何变量,就开始使用指针。解决方案:在定义指针时,使指针指向NULL
指针运算
  • 给一个指针加1表示要让指针指向下一个变量
  • 如果指针不是指向一片连续分配的空间,如数组,则这种运算没有意义
    //*(p+1)--->a[1]
    int a[10];
    int *p=a;
    
  • 算术运算可以对指针做:
    • 加减一个整数(+,+=,-,-=)
    • 递增递减(++/--)
    • 两个指针相减
  • *p++
    • 取出p所指的数据,完事后顺便把p移到下一个位置
    • *的优先级虽然高,但是没有++高
    • 常用于数组类的连续空间操作
    • 在某些CPU上,这可以直接被翻译成一条汇编指令
  • 指针比较
    • <,<=,==,>,>=,!=都可以对指针做
    • 比较他们在内存中的地址
    • 数组中的单元地址肯定是线性递增的
  • 0地址
    • 内存中有0地址,但是0地址通常是个不能随便碰的地址,所以指针不应该具有0值
    • 因此可以用0地址来表示特殊的事情:
      • 返回的指针是无效的
      • 指针没有真正被初始化
      • NULL是一个预定定义的符号,表示0地址
      • 有的编译器不愿意你用0来表示0地址
指针的类型

无论指向什么类型,所有的指针的大小都是一样的,因为都是地址,但是为了避免用错指针,指向不同类型的指针是不能直接互相赋值的

动态内存分配

用于输入数组:如果输入数据时,先告诉你个数,然后再输入,要记录每个数据

int *a = (int*)malloc(n*sizeof(int));
  • malloc
    • # include
    • void* malloc(size_t size);
    • 向malloc申请的空间的大小是以字节为单位的
    • 没空间:如果申请失败则返回0,或者叫做NULL
    //malloc动态内存分配
    #include 
    #include 
    
    int main(void){
        int number;
        int *a;
        int i;
        printf("输入数量:");
        scanf("&d",&number);
        //int a[number];  C99
        a = (int*)malloc(number*sizeof(int));
        for(i=0;i=0;i--){
            printf("%d",a[i]);
        }
        free(a);
        return 0;
    }
    
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/347149.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号