精华内容
下载资源
问答
  • 当使用等号=将一个变量的值赋给另一个变量时,如 j = i ,实际上是在内存中将 i 的值进行了拷贝。可以通过 &i 获取变量 i 的内存地址 指针类型:简单地说go语言的指针类型和C/C++的指针类型用法是一样的,除了出去...
  • 引用more effective c++ 中的解释:  指针与引用看上去完全不同指针用操作符’*’和’->’,引用使用操作符’.’),但是它们似乎有相同的功能。...因此如果你使用一个变量并让它指向一个对象,但是该变量
    引用more effective c++ 中的解释:
      指针与引用看上去完全不同(指针用操作符’*’和’->’,引用使用操作符’.’),但是它们似乎有相同的功能。指针与引用都是让你间接引用其他对象。你如何决定在什么时候使用指针,在什么时候使用引用呢?

      首先,要认识到在任何情况下都不能用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以把变量声明为引用。

      “但是,请等一下”,你怀疑地问,“这样的代码会产生什么样的后果?”

      char *pc = 0; // 设置指针为空值

      char& rc = *pc; // 让引用指向空值

      这是非常有害的,毫无疑问。结果将是不确定的(编译器能产生一些输出,导致任何事情都有可能发生),应该躲开写出这样代码的人除非他们同意改正错误。如果你担心这样的代码会出现在你的软件里,那么你最好完全避免使用引用,要不然就去让更优秀的程序员去做。我们以后将忽略一个引用指向空值的可能性。

      因为引用肯定会指向一个对象,在C里,引用应被初始化。

      string& rs; // 错误,引用必须被初始化
      string s("xyzzy");
      string& rs = s; // 正确,rs指向s

      指针没有这样的限制。
      string *ps; // 未初始化的指针
                // 合法但危险

      不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。

      void printDouble(const double& rd)
      {
       cout << rd; // 不需要测试rd,它
      }       // 肯定指向一个double值

      相反,指针则应该总是被测试,防止其为空:

      void printDouble(const double *pd)
      {
       if (pd)
       {// 检查是否为NULL
        cout << *pd;
       }
      }

      指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变。

      string s1("Nancy");
      string s2("Clancy");

        string& rs = s1; // rs 引用 s1
      string *ps = &s1; // ps 指向 s1
      rs = s2; // rs 仍旧引用s1
              // 但是 s1的值现在是"Clancy"

        ps = &s2; // ps 现在指向 s2;// s1 没有改变

      总的来说,在以下情况下你应该使用指针,一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。

      还有一种情况,就是当你重载某个操作符时,你应该使用引用。最普通的例子是操作符[]。这个操作符典型的用法是返回一个目标对象,其能被赋值。

      vector<int> v(10); //建立整形向量(vector),大小为10
                        //向量是一个在标准C库中的一个模板(见条款35) 
      v[5] = 10; // 这个被赋值的目标对象就是操作符[]返回的值

      如果操作符[]返回一个指针,那么后一个语句就得这样写:

      *v[5] = 10;

      但是这样会使得v看上去象是一个向量指针。因此你会选择让操作符返回一个引用。(这有一个有趣的例外,参见条款30)

      当你知道你必须指向一个对象并且不想改变其指向时,或者在重载操作符并为防止不必要的语义误解时,你不应该使用指针。而在除此之外的其他情况下,则应使用指针 。
    展开全文
  • C++ 指针

    2010-07-19 22:53:00
    一个指针所存放的是某个变量的地址值,称为这个指针指向被存放地址的变量。指针存放哪个变量的地址值,它就指向那个变量。指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,因为任何数据值的类型是...

    指针是一种特殊的变量。它是用来存放某个变量的地址值的一种变量。这一点与一般变量不同。指针变量所表示的数据值是某个变量的在内存中的地址值。一个指针所存放的是某个变量的地址值,称为这个指针指向被存放地址的变量。指针存放哪个变量的地址值,它就指向那个变量。

    指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,因为任何数据值的类型都是unsigned long int型的。由于指针度类型是它所指向的变量度类型,而所指向变量的类型不同,则指针的类型也不同。指针可以指向各种类型的变量还可以指向数组(或数组元素),可以指向函数,可以指向文件,还可以指向指针。

    定义指针: int a(5);

                    int *P = &a;

    把一个值(内存的某个地址)赋值给指针需要使用“取地址”操作符(&)

    int myInt = 904;

    int *myPoniter;

    myPointer = &myInt;

     

     

    定义一个指针后,系统便给指针分配一个内存单元,各种不同类型度指针所被分配的内存空间的大小是相同的,因为不同类型的指针存放的数据值都是内存地址。

    各类型的指针定义格式如下:

    <类型>*<指针名>=<初值>,...;

    如,int *p; //pi是一个int型指针

    char *pd;   //pc是一个字符指针

    double *pd;    //pd是一个double型指针

    int(*pa)[5];      //pa是一个指向一维数组的指针,它指向5个int型元素的一维数组

    int(*pf)();         //pf是一个指向类型为int型的函数的指针

    int **pp;    //pp是一个指向int型指针的指针

     

     知道了某个变量在内存中的地址,就可以利用指针访问位于该地址的数据。这需要对指针做解引用(deference)处理--在指针名的前面加上一个星号*。

    在某些场合只有通过指针才能改变某个变量的值。

     

    引用不同于指针,它不是变量,它不占内存,它本身无内存地址,它的地址值是它引用的变量的地址值。引用通常被认为是另一种变量的别名。引用只是被引用的变量或对象的替身。一般定义引用时必须初始化。如:int a = 3;

    int  &m= a; 这里m是一个引用,它是变量a的别名。所有的引用上所施加的操作,实质上就是在被引用者上的操作。

     

    指针是通过地址间接访问某个变量,而引用是通过别名直接访问某个变量。引用必须初始化,一旦被初始化后不得再作为其他变量的别名。

    指针的运算:

    (1)赋值运算

    (2)一个指针可以加减一个整型数

    (3)在一定条件下,指针可以相减

    (4)在一定条件下,指针可以比较

     

    数组元素可以用下标表示,也可以用指针表示,采用指针表示往往优于下标表示。

    如,int a[i] 指针表示为 *(a+i)

     

     

     

    总结:

    星号*有两种用途:

    一是创建指针:int *myPointer = &myInt;

    二是对指针进行解引用: *myPointer = 23;  //*myPointer = myInt

    数组的名字同时也是一个指向其第一个元素的指针

     

    展开全文
  • 指针和参数传递(Go语言)

    千次阅读 2020-09-09 21:23:05
    一个指针变量可以指向任何一个值的内存地址 获取变量的地址 ​ Go语言的取地址符&,一个变量前使用&,会返回该变量的内存地址。 func main(){ a := 110 fmt.Printf("变量的地址:%x\n",&a) } ...

    指针

    概述

    • 指针是存储另一个变量的内存地址的变量

      • 变量是一种使用方便的占位符,变量都指向计算机的内存地址
      • 一个指针变量可以指向任何一个值的内存地址
    • 获取变量的地址

      ​ Go语言的取地址符&,一个变量前使用&,会返回该变量的内存地址。

      func main(){
      	a := 110
      	fmt.Printf("变量的地址:%x\n",&a)
      }	
      
    • 指针特点

      • 指针不能运算(不同于c语言)
      • Go语言中如果对指针进行运算会报错

    声明指针

    *T是指针变量的类型,它指向T类型的值。

    var 指针变量名 *指针类型

    • *号用于之sing变量是一个指针
    • var ip *int //指向整型的指针
    • var fp *float64 //指向浮点型的指针

    指针使用流程

    1. 定义指针变量
    2. 为指针变量赋值
    3. 访问指针变量中指向地址的值
    4. 获取指针的值:在指针类型的变量前加上*号来获取指针所指向的内容

    空指针

    GO 空指针

    • 当一个指针被定义后没有分配到任何变量是,它的值为nil
    • nil指针也称为空指针
    • nil在概念上和其他语言null,NULL一样,都指代零值或空值
    • 一个指针变量通常缩写为ptr

    空指针判断

    if(ptr != nil)
    if(ptr == nil)
    

    指针数组

    指针数组:就是元素为指针类型的数组。

    • 定义一个指针数组
      • var ptr [3]*string
    • 有一个元素个数相同的数组,将该数组中每个元素的地址赋值给该指针数组。也就是说该指针数组与某一个数组完全对应
    • 可以通过*指针变量获取到该地址所对应的数值

    双重指针

    1. 如果一个指针变量存放的有事另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。

      当定义一个指向指针的指针变量是,第一个指针存放第二个指针的地址,第二个指针存放变量的地址

    2. 声明格式如下

      ```go
      

      var ptr **int
      //以上指向指针的指针变量为整形
      //访问指向指针的指针变量值需要使用两个*号

      ```
      
      ```
      

    函数参数传递

    函数如果使用参数,该参数变量称为函数的形参。形参就像定义在函数体内的局部变量。调用函数,可以通过两种方式来传递参数:值传递和引用传递。

    值传递

    概念

    值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改将不会影响到原内容数据。

    • 默认情况下,Go语言使用的是值传递,即在调用过程中不会影响到原内容数据
    • 每次调用函数,都将实参拷贝一份在传递到函数中。每次拷贝一份,性能就下降了。GO语言中使用指针和值传递配合避免了性能降低。

    引用传递

    概念

    引用传递:是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到原内容数据

    • 严格来说Go语言只有值传递一种传参方式,Go语言没有引用传递的
    • Go语言中可以借助指针来实现引用传递的效果。函数参数使用指针,传参时其实是在拷贝一份指针参数,也就是拷贝了一份变量地址
    • 函数的参数如果是指针,当函数调用时,虽然参数仍然是按拷贝传递的,但拷贝仅仅是个指针(一个内存地址),这样就可以减少实参拷贝造成的内存浪费,时间开销,性能降低的情况

    作用

    • 传指针使得多个函数能操作同一个对象
    • 传指针更轻量级(8bytes),只需要传内存地址。如果参数是非指针参数,那么值传递的过程中,每次在拷贝上面就会花费较多的系统开销。所以当要传递大的结构体的时候,用指针是一个明智的选择
    • Go语言中的slice,map,channel类型的实现机制都是类似指针,所以可以直接传递,而不必取地址后传递指针
    展开全文
  • 在上一篇中,咱们弄清楚指针和引用的基本区别,...Secondly, 若用某变量(对象)指向一个变量(对象),且该变量(对象)具备指向任何对象的能力,这时最好将变量(对象)声明为指针,因为指针可以指向任何变量

    在上一篇中,咱们弄清楚指针和引用的基本区别,下面从「高质量c++编程」的角度剖析指针与引用

    一、什么时候用 指针与引用?

    • 首先,有几个意识。
    • Firstly,      任何情况下引用都不能用指向空值,引用必须总是指向某个对象。
    • Secondly, 若用某变量(对象)指向另一个变量(对象),且该变量(对象)具备指向任何对象的能力,这时最好将变量(对象)声明为指针,因为指针可以不指向任何变量(对象
      //空指针(null pointer)不指向任何对象,所以使用指针前一般先进性检查操作,检验指针是否为空:
      // 先介绍3中生成空指针的方法
      int *p1  = nullptr;   // equals to : int *p1 = 0; 【C++11新标准】
      int *p2 = 0; // 直接将指针初始化为字符常量 0
      int *p3 = NULL;   // equals to : int *p3 = 0;
      
      // 后面会紧接着介绍 测空

    • 相反,如果变量肯定指向一个非空变量(对象),这时就把变量声明为引用。下面举一个“毒代码”:
    • char *pc = nullptr;// 设置指针为空值
      char & rc = *pc;// 让引用指向空值 
      这是非常有害的,编译器仍然产生输出,不过,鬼知道结果,这个不确定的输出将摧毁你整个代码大厦(编译器能产生一些输出,导致任何事情都有可能发生)。
    • 另一外测试代码:
    • #include <iostream>
      //#include <vector>
      using namespace std;
      
      void fun( int *x ){
      	x = x + 1;  // 注意这段代码,对指针[而非指针变量]进行加1操作,结果将不可预测
      }
      	
       int main()
      {
      	cout << "请输入1个整数:" << endl;
      	int i1;
      	cin  >> i1;
      	fun( &i1 );
      	cout <<"i1 = " << i1 << endl;
      	system("pause");
      	return 0;
      }




    • 由局部变量变化可知,编译器仍然产生输出,x 本身表示指针的值(地址值),指针值(地址值)+1后对应新的内存单元(地址值),新的内存单元中对应的变量值为{-858993460} = 2^33 - 32;相当于地址变化,但 i1 的值由于对应着固定的内存单元并不发生变化。 

      测试代码继续上:
    •  string &rs;// 错误,引用必须被初始化
       string str("xy32y");
       string &rs = str;// 正确,rs指向s  指针没有这样的限制。
       string *ps;// 未初始化的指针,合法但危险, 应尽量避免
      这也意味着前面一篇文章中所提到的引用的空间和时间优势,时间上更快,占用内存更小。

    •  void printDouble1(double  &rd)   // 这里提一下,引用没有 const,指针有 const; 
      {
           cout << rd; // 不需要测试rd,它肯定指向一个double值
      }
      相反,指针则应该总是被测试,防止其为空:
      void printDouble2(const double *pd)
      {
           if (pd)  // if (true)  若非空指针,即指针指向一个内存单元
           { // 检查是否为NULL
                 cout << *pd;
           }
      }

      指针可以被重新赋值以指向另一个不同的对象引用can only指向在初始化时被指定的对象,不能改变
    • string s1("Nancy");
      string s2("Clancy");
      string &rs = s1; // rs 引用 s1
      string *ps = &s1; // ps 指向 s1
      rs = s2; // rs 仍旧引用s1, 但是rs传递的是实参, 故s1的值被赋值为"Clancy"
      ps = &s2; // ps 现在指向 s2; 喜新厌旧,换了新对象

      小结:一 存在不指向任何对象的可能(在这种情况下,你能够设置指针为空)=>指针
    •   二 在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)=>指针
    •           三 总指向一个对象,且之后不改变指向 => 引用
    •   四 重载某个操作符 = > 引用
    • 重点拆解一下
    • 最普通的例子是操作符[].这个操作符典型的用法是返回一个目标对象,其能被赋值。
    • vector<int> v(10); // 建立整形向量(vector),大小为10;
      // 向量是一个在标准C库中的一个模板(见条款35)
      v[5] = 10; // 这个被赋值的目标对象(变量)就是操作符[]返回的值
      如果操作符[]返回一个指针,那么后一个语句就得这样写:
      *v[5] = 10;
      但是这样会使得v看上去象是一个向量指针。因此你会选择让操作符返回一个引用。(这有一个有趣的例外,参见条款30)
      当必须指向一个对象且不改变其指向时,或者在重载操作符并为防止不必要的语义误解时,应使用引用。而在除此之外的其他情况下,则应使用指针
      void fun(int *p, int &r);
      int a = 1;
      int b = 1;
      fun(&a, b);


    • 指针本身的值(地址值)是以passby value进行的,你能改变地址值,但这并不会改变指针所指向的变量的值
      p = some other pointer;// 起始地址值随机值, 右移一位后地址值改变一个int型长度4 Byte, 输入的整数位333, i1 依旧为 333【见图一】
      但能用指针来改变指针所指向的变量的值,
    • 倘若红线处 修改为“ *x = *x +1 ”, 则有
      *x = 333+1; // 且指针所指变量 i1 将也加1 变为 334【见图二】
    • 如下面两个图:
    • 图一
    • 图二


    • 摘自《「高质量c++编程」》,不过下面这些着实是等到使用者达到一定经验才会遇到。
    • 尽可能使用引用,实在不得已,使用指针。
    • 引用出现的典型场合是对象的表面,而指针用于对象内部。
      当你不需要“重新指向”时,引用一般优先于指针被选用。这通常意味着引用用于类的公有接口时更有用,不过博主真的很喜欢这句话,“程序员 应该针对要解决的问题写代码,而不是不经思考的套娃,高效,简洁,质优才是一个程序员应该追求的”


    展开全文
  • 指针和引用

    2016-06-10 22:00:40
    如果声明一个变量并让它指向一个对象,但是该变量某些时候可能也不指向任何对象,这时应该把变量声明为指针,这样可以赋空值。引用不允许指向空值。 (2)合法性区别:使用引用之前不需要测试它的合法性,相反,...
  • 指针与引用

    2011-05-02 15:05:00
    因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空...
  • 因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空...
  • 指针与引用

    2011-05-21 10:34:00
    因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量
  • 指针和引用的区别

    2018-10-08 21:21:47
    指针和引用的区别: 1,非空区别: 在任何情况下不能使用指向空值的引用。...指针可以被修改以指向另外一个不同对象,但是引用则只能指向初始化时被指定的对象,但是其内容可以被修改。 3,应用区别: ...
  • 指针与引用看上去完全不同指针...因此如果你使用一个变量并把它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一...
  • 指针与引用的区别

    2010-07-11 11:27:00
    因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空...
  • 按照我的理解,一言蔽之,就是一个指针。这确实和之前学过的强类型语言是有不同的。 为什么这么说呢?首先,python中的变量是没有类型的,有类型的是“对象”,而不是变量变量没有类型,那么就意味着它可以随意...
  • 指针与引用区别

    2019-05-05 21:29:27
    可修改区别:指针可以被重新赋值以指向一个不同对象,但是引用总是在初始化时被指定了绑定的变量,以后不能改变,也就是不能被重新赋值,但是其内容可以改变。 应用区别:在以下情况下应该使用...
  • <1>非空区别。在任何情况下不能使用指向空值的引用,引用定义时必须初始化。如果你使用一个变量并让它...可修改区别,指针可以重新被赋值以指向一个不同的对象,引用总是指向在初始化时被指定的对象,以...
  • 因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量
  • 指针与引用看上去完全不同指针用操作符“*”,引用使用操作符“&”),...因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值
  • 相同:指针与引用看上去完全不同,...(如果变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以变量声明为引用)2):引用必须被初始化;而指针可以不被初始化。例如下面的例子 string &str;// ...
  • 在很多人眼里,C语言的指针和数组是等价的。几乎在任何时候数组都可以指针来替换,这...而对于int a[10]而言,我们常常可以在一些书上看到a指向数组的第一个元素,似乎它也是个指针变量,变量的值是a[0]的地址。这与i
  • C语言指针4-内存的灵活操作

    千次阅读 2010-11-06 12:08:00
    (1)我们定义的任何一个类型的任何一个变量,在程序运行时占用一定的内存空间。 (2)指针的sizeof大小是4字节(32位),可以指向任何内存空间,可以做任何类型的强制转换。 (3)当我们定义的...
  • 一个指针变量可以指向一个数组,也可以指向一个数组元素, 可把数组名或第一个元素的地址赋予它。如要使指针变量指向第i号元素可以把i元素的首地址赋予它或把数组名加i赋予它。  设有实数组a,指向a的指针变量...
  • 不同类型的变量在内存中占用存储空间的大小可以不一样 switch语句中必须含有defualt语句和break语句 指针变量是把另一个变量的地址作为其值的变量 表达式 625%2.5 是合法的C语言表达式 若指针变量指向一维数组的第...
  • 3.1指针与引用的区别: 首先,要认识到在任何情况下不能使用指向空值的引用...指针与引用的另一个重要的不同指针可以被重新赋值以指向一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变。
  • 基础议题 M1.指针与引用类型的选用 1.任何时候不能使用...3.指针与引用的一个重要区别是:指针可以指向NULL,而且可以重新指向另一个不同的对象,而引用初始化时被指定对象,之后不能改变。 4.当你重载某些操作符的
  • 1.6 我想声明一个指针,并为它分配一些空间,但却不行。这样的代码有什么问题?char *p; *p=malloc(10); 33 声明风格 33 1.7 怎样声明和定义全局变量和函数**好? 33 1.8 如何在C中实现不透明(抽象)数据类型? ...
  • 第1章 声明和初始化 基本类型 1.1 我该如何决定使用哪种整数类型? 1.2 为什么不精确定义标准类型的大小...*7.5 一个指针变量分配多少内存? 7.6 我使用fgets将文件的所有行读入一个数组,为什么读入的每一行是...
  • 1.6 我想声明一个指针,并为它分配一些空间,但却不行。这样的代码有什么问题?char*p;*p=malloc(10);  声明风格  1.7 怎样声明和定义全局变量和函数最好? 1.8 如何在C中实现不透明(抽象)数据类型?  1.9 ...

空空如也

空空如也

1 2 3 4 5 6
收藏数 103
精华内容 41
关键字:

任何一个指针变量都可以指向不同