• c语言指针


    1.取地址符&

      &用来取变量的地址

      输出变量的地址的时候使用:

        printf("%p",a)      //虽然有时候print("%d",&a)也能输出地址,但是这可能不是真正的a的地址,假如地址用8个字节表示,%d输出会默认向int类型转换,导致前面一部分数据丢失。

      &只能对变量操作,下面这些都是错误的:

        &(a+b)

        & (a++)

      对于数组  int a[50]

      &a=a=&a[0],数组a的地址连续分配,假如a[0]是 0000 0000,则a是 0000 0004

      

      在一个程序中,分配两个变量的时候,地址是从高到低分配的,因为这些变量存储在堆栈中,而堆栈是从上到下分配地址,例如

      int a,b;

      printf("%p     %p",a,b)    // 0001 0004       0001 0000

    2.指针

      指针就是保存地址的变量,前面提到过%d输出地址的时候可能会导致部分数据丢失,而指针就不会。

      声明一个指针: 变量类型 *p 或者 变量类型* p  //注意*是修饰p的,而不是修饰变量类型的

      int *p,q  //表示声明了一个指针q和一个int型变量q

      int* p,q  //同上

    3. * 作为单目运算符

      *p 作为单目运算符的时候表示取地址p指向的内容

      *p =26     可以通过这种方式改变指针p指向的变量的内容

      & 和 * 是两种相反的运算符,一个取地址,一个取地址所指向的变量的值

    4. scanf("%d",i)

      编译的时候可能不会报错,因为某些电脑是32位的,地址就是32位的,跟int型变量的长度可能一样,因此scanf函数会把i的值当作地址,但是运行的时候就很可能出错了,因为i的值一般不大,而低地址在内存中往往是操作系统或者其他程序使用的。

    5.指针的使用场景

      -swap交换两个变量的值

      -传给函数的参数实际是需要带回结果的变量,这样的返回值有多个,而函数return 语句只能返回一个变量

      -函数返回运算状态(成功/失败),指针返回运算结果。通常0表示成功,-1表示失败,当结果也可能取到-1/0时,就必须用指针返回,return 返回成功/失败的结果

      -当传递很大的数组或者结构体的时候,可以使用指针传递,当希望这些数组或者结构体不被修改的时候,可以使用 fun(int const * p)或者fun(const int a[])(这种只适用于数组)

    6.指针最常见的错误

      -定义指针之后没有赋值就直接使用 ,即指针需要赋值之后才能使用 *指针 来读取指针所指向的变量,因为假如不初始化赋值指针,指针所在的内存单元存的值是未初始化的(随机的),因此指针指向的内存单元是未知的,运行的时候很有可能出错。

    7.传入函数的数组的本质

      函数参数表中的数组实际是指针

      fun(int a[])、fun(int *a)、fun(int *)以及fun(int [])四种函数原型是等价的

      在函数fun里面使用sizeof(a)其实是指针变量的size,这里也就是8字节的长度,我的电脑是64位的。只有在main函数里面使用sizeof,才表示数组的长度x数据类型的长度

      int b[] =a    //a是数组,这里是非法的,因为int b[] 等价于 int * const b,即数组一旦创建,其地址是无法改变的,因为地址要分配一段连续的内存,如果改变,无法保证改变后的地址后续连续的地址可以使用。

    8.指针与const    //这里的内容只适用于C99

      int * const p=&a;

      *p=26;  //OK

      p++;  //Error,这种情况是不能修改指针变量的值的

      const int *p=&a;

      *p=26;  //Error,这种情况是不能通过p修改a的,但是a可以修改

      a=26;  //OK

      p=&b;  //OK

      总结:判断哪个不能修改是看const是在*前面还是后面,如果在前面,表示不能通过指针修改变量的值,如果在后面表示不能修改指针,因此 int const * p 和const  int * p等价

    9.const 数组

      const int a[5]={1,2,3,4,5}  //表示数组里面的每一个值都不能改变,而且数组必须通过这种初始化来赋值

  • 相关阅读:
    C# 调用C++ dll 返回char*调用方式(StringBuilder乱码)
    Linux/Centos下安装部署phantomjs
    SQLEXPR_x64_CHS、SQLEXPRADV_x64_CHS、SQLEXPRWT_x64_CHS、SqlLocalDB、SQLManagementStudio_x64_CHS各版本说明
    linux安装phantomjs,-bash: /usr/local/bin/phantomjs: is a directory解决方案
    [转]EAS BOS MsgBox使用大全
    SQL 2005用Windows身份验证登陆18456错误
    [原]EAS动态扩展平台(DEP)服务端调用oracle存储过程
    Uuid, BOSObjectType, BosUUid 区别
    [转]oracle job有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务。
    [转]如何拷贝一个 SQL Server 的表
  • 原文地址:https://www.cnblogs.com/foodie-nils/p/13159348.html
Copyright © 2020-2023  润新知