1.引用的本质
struct typeA
{
  int &a;
}
struct typeB
{
  int *a;
}
int main(void)
{
  cout<<sizeof(struct typeA)<<endl;//输出4
  cout<<sizeof(struct typeB)<<endl;//输出4
  int a =10;
  int &re =a;//常量要初始化,引用也要初始化,引用可能是一个常量
  //综上两点,引用可能是一个常指针;
  int *const p=&a;//常指针
}
//引用占用的大小和指针是一样的

struct student
{
  int id;
  char name[64];
}

//修改a所指向量的值
void motify(int *const a)
{
  *a=300;
  a++;//这个是不可以的,可以改变a的值,不能改变a的方向。
}
//修改a所指向量的值
void motify2(int &a)
{
  a=300;//对一个引用赋值的时候,编译器替我们隐藏*操作
}
//
int main(void)
{
  int a = 2;
  motify(&a);//因为引用就是常指针
  motify2(a);//当我们将引用作为函数参数传递时,编译器,会替我们将实参,取地址给引用
}
//在研究引用的时候,可以将引用当做一个指针常量去研究
//当使用引用的时候,将引用当做变量的别名
//总体来说,在作为形参的时候,将引用作为常指针,并且做操作的时候,编译器会隐藏*(取内容运算)操作,直接a=...;
//在作为实参的时候,编译器会隐藏&(取地址运算)操作。

2.常量
在C++中,有分常量区和栈。
int array[10];//在栈中开辟10个int的空间,在常量区放置array名字的变量,值是这10个int的第一个地址。
int &r=a;//在常量区放置一个r名字的变量,值是栈中a的地址

3.引用作为函数的返回值
int getA1()
{
  int a=10;
  return a;//拷贝a的值,并返回,a被销毁
}
int& getA2()
{
  int a=10;
  return a;//返回一个const int &temp=a;
}
int main(void)
{
  int a =0;
  a= getA1();//拷贝getA1中的a值
  int mian_a=10;
  mian_a=getA2();//mian_a=temp,temp是a的别名,数值拷贝,如上,隐藏了*操作,操作完这步,a才会被销毁
  int &mian_a_re=getA3();//又将temp赋值给main_a_re,a的别名变为mian_a_re,a没有被销毁
  //如果对mian_a持续往下操作,mian_a(常指针)所指向的值将会不正常,因为局部变量a本该被销毁的,因为a的方法栈中。
}
//如果引用作为返回值,不要返回局部变量的引用。
***
int& getA3()
{
  static int a = 10;//这里倒是可以这样,因为static是另外开辟空间的。而且这句只会被执行一次。
  return a;
}
//当然也可以getA3()=1000;来搞,因为getA3()相当于int *const temp,但是编译器在赋值和取值,又会帮忙*temp

4.指针引用
struct teacher
{
  int id;
  char name[64];
}
int get_men(struct teacher** tpp)
{
  struct teacher *tp=NULL;
  tp=(struct teacher*)malloc(sizeof(stuct teacher));
  //malloc是动态申请一块内存,并返回*void指针,*void指针相当于未确定类型的指针
  if(tp==null)
  {
    return -1;
  }
  tp->id=100;
  strcpy(tp->name,"LaoWang");
  *tpp=tp;//赋值
  return 0;
}
//跟上面a不一样了,因为malloc是申请的内存,要手动释放才释放,而a作为局部变量,方法执行完要自动释放
void free_teacher(struct teacher **tpp)//tpp是指向指针的指针
{
  if(tpp==NULL)
  {
    return;
  }
  struct teacher *tp=*tpp;//对tpp进行*tpp,取得的是指向teacher的指针
  if(tp!=NULL)
  {
    free(tp);
    *tpp=null;//还要记得搞掉*tpp的指向
  }
}
****不作struct teacher的结构体拷贝,纯粹使用指针完成,struct teacher实际只开辟了一次内存
int main(void)
{
  struct teacher *tp=NULL;
  get_mem(&tp);//tp本来是指针,再&一次,就是指向指针的指针。
  //...
  free_teacher(&tp);
}
以下使用引用方式地址传递:
int get_mem2(struct teacher * &tp)//指向teacher*(指向teacher的指针)的常指针,使用时,按指向teacher的指针的别名
{
  tp=(struct teacher*)malloc(sizeof(struct teacher));
  if(tp==NULL)
  {
    return -1;
  }
  tp->id=100;
  strcpy(tp->name,"LaoWang");
  return 0;
}
void free_teacher2(struct teacher *&tp)//相当于const struct teacher **tp,在使用时,tp当作是一个指向struct teacher的指针变量的别名。
{
  if(tp!=NULL) //相当于*tp,编译器自动取进行*取内容运算
  {
    free(tp);
    tp=NULL;
  }
}
int main(void)
{
  struct teacher *tp=NULL;
  get_mem2(tp);//编译器自动取地址操作&,传入的是指向(指向tp的指针),二级指针
}
//助记,使用时,分两部分看
类型A B;
类型A &dd=B;
//dd是类型A的变量的别名,对dd操作,相当于对变量本身的操作,无论传到哪里都好;
Function(typeA &p);
//使用引用传递,没有内存开辟。
//调用
typeA a=....;
Fuction(a);
//填写typeA变量,那么p代表a,操作p等于操作a;
E.g 如果typeA是指针型变量,那么操作p相当于操作一个指针。
typeA &Function()
{
  typeA a=...;
  Return a;
  //语法上,返回一个typeA型变量,实际上返回a本身。
  //不用引用时,是返回a的copy(释放内存又开辟内存),而引用,这是a本身,(释放内存又强行返回引用,如果a是局部变量)
  //所以不要返回局部变量的引用
}
typeA &p=Function();
//操作p就相当于操作a本身,free(&p)就相当于free(&a)本身,&是取地址运输,&a相当于typeA*型。
//引用是个奇特的东西,介于常指针和变量之间

5. const引用
const引用常用于函数形参
void function()
{
  const int a =10;
  int &re=a;//报错,如果想对常量进行引用,必须使用const引用,因为re的安全性高于a
  const int &re=a;//不报错
  int b =20;
  const int &re2=b;//不报错 ,用比较安全的re2来引用不那么安全的b是可以的
  re2=300;//报错,按理re2是b的别名,对其操作相当于对b操作,但这里不行,所以常用于函数形参以提高内存效率,并且保护原值。
}
//
//方法执行时,产生的临时变量放在栈(根据内存的用途,对内存的称呼)中,当方法执行结束后,在执行其他方法时,上一个方法开辟的内存就会被做其他用途,这个过程叫“压栈”
//
void main()

{

  //(1)变量初始化,再const引用 变量

  int b = 10;

  const int &a = b;

  b = 11;//b是可以修改的,但是a不能修改

  printf("a=%d,b=%d\n", a, b);
  //最终输出a和b都是11,证明a依然代表b,只是不能通过a修改b
  system("pause");

}
6. const引用和const函数
class A
{
  public:
  int getLenght1()//实际上会编译为 int getLenght(int *const this),const指针,指向不可变
  {

  }
  //
  int getLenght2() const //实际上为const int *const this,相当于const引用,指向内容不可变,指向不可变 , 相当于const A &a
  {

  }
}

// 不能通过const引用修改变量的值
void function(const A &a) //为了保护a不在方法中被改变
{
  a.getLenght1(); //这里出错,用高安全的引用作为实参,调用低安全形参的函数。
  a.getLenght2(); //这里才不会出错
}

7.
const变量:const int a;
指向const变量的指针: const int *a;
const指针:int *const a
(助记,const离那个近,那个就“常”)

8. 标明为const的变量,在const区有独立的地址

int main(void)

{

  const int a =1;

  int *p=(int * )&a;

  *p=10;//在C语言中,a的变量已经变为10了;但是在C++中,a的独立在const区那部分的内存的,&a操作,实质是上是开辟一个临时变量,将地址给P了。

}

C++学习笔记1_ 指针.引用的更多相关文章

  1. Dubbo -- 系统学习 笔记 -- 示例 -- 泛化引用

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 泛化引用 泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值 ...

  2. 吴裕雄--天生自然C++语言学习笔记:C++ 引用

    引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字.一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量 C++ 引用 vs 指针 引用很容易与指针混淆,它们之间有三个主要的 ...

  3. Linux学习笔记1_用户和权限

    自从我大微软终于放下身段,决定给开源社区一个迟来的拥抱,追随多年的拥趸们像是突然得到了女神的垂青,各种茫然失措.痛哭流涕.欢欣鼓舞,纷纷唱了起来:“等了好久终于等到今天,梦了好久终于把梦实现……”唱完 ...

  4. 《C语言学习笔记》指针数组及其应用

    C语言中,最灵活但又容易出错的莫过于指针了.而指针数组,是在C中很常见的一个应用.指针数组的意思是说,这个数组存储的所有对象都为指针.除了存储对象为指针,即一个地址外,其它操作和普通数组完全一样. # ...

  5. c++学习笔记——智能指针

    智能指针是为了便于管理动态内存,能够自动管理释放所指向的对象. 智能指针共有三种:1.shared_ptr允许多个指针指向同一个对象:2.unique_ptr独占所指向的对象:3.weak_ptr是一 ...

  6. C++学习笔记29,引用变量(1)

    引用变量在创建的时候就必须初始化.无法创建一个未被初始化的引用. #include <iostream> using namespace std; int main() { int x=1 ...

  7. JS学习笔记1_基础与常识

    1.六种数据类型 5种基础的:Undefined,Null,Boolean,Number,String(其中Undefined派生自Null) 1种复杂的:Object(本质是一组无序键值对) 2.字 ...

  8. JavaScript学习笔记1_基础与常识

    1.六种数据类型 5种基础的:Undefined,Null,Boolean,Number,String(其中Undefined派生自Null) 1种复杂的:Object(本质是一组无序键值对) 2.字 ...

  9. go学习笔记-语言指针

    语言指针 定义及使用 变量是一种使用方便的占位符,用于引用计算机内存地址.取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址. 一个指针变量指向了一个值的内存地址.类似于变量和常量, ...

随机推荐

  1. POJ 2386——Lake Counting(DFS)

    链接:http://poj.org/problem?id=2386 题解 #include<cstdio> #include<stack> using namespace st ...

  2. Elasticsearch全文检索学习

    ElasticSearch官方网址:https://www.elastic.co ElasticSearch官方网址(中文):https://www.elastic.co/cn/ Elasticsea ...

  3. [scrapy-redis] 将scrapy爬虫改造成分布式爬虫 (2)

    1. 修改redis设置 redis默认处在protection mode, 修改/etc/redis.conf, protected-mode no, 或者给redis设置密码, 将bind 127 ...

  4. FFmpeg(一)

    1. FFmpeg分为3个版本:Static.  Shared. Dev 前两个版本可以直接在命令行中使用.包含了三个exe:ffmpeg.exe,ffplay.exe,ffprobe.exe Sta ...

  5. scrapy架构流程

    1.爬虫spiders将请求通过引擎传递给调度器scheduler 2.scheduler有个请求队列,在请求队列中拿出请求给下载器,downloader 3.downloader从Internet的 ...

  6. 【Oracle】SQL语句优化

    (1) 选择最有效率的表名顺序(只在基于规则的优化器中有效):  ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最 ...

  7. 无意间做了个 web 版的 JVM 监控端(前后端分离 React+Spring Boot)

    之前写了JConsole.VisualVM 依赖的 JMX 技术,然后放出了一个用纯 JMX 实现的 web 版本的 JConsole 的截图,今天源码来了. 本来就是为了更多的了解 JMX,第一步就 ...

  8. execute,executeQuery,executeUpdate

    Statement的execute(String query)方法用来执行任意的SQL查询,如果查询的结果是一个ResultSet,这个方法就返回true.如果结果不是ResultSet,比如inse ...

  9. Java 语言特点

    引入<Java核心技术:Ⅰ> 1. 简单性 Java 语法是 C++ 语法的一个“ 纯净” 版本.这里没有头文件. 指针运算(甚至指 针语法).结构. 联合.操作符重载. 虚基类等.如果你 ...

  10. python服务端工程师就业面试指导☝☝☝

    python服务端工程师就业面试指导 由Python专业面试官打造的课,少之又少,专业代表着经验,代表着对考察点的通透理解,更代表着对你负责 第1章 Python工程师offer直通车(视频+教辅文档 ...