C&C++

Pointer

2020-03-25 10:00:00 +0800

C的指针

Pointer_C指针_C++指针_Golang指针

  • 内存的硬件在软件层面的抽象
    • 一维线性,M个连续的1个字节大小的单元组成的数组,每个字节有连续且唯一的物理地址 Physical Address
    • CPU访问内存最自然的方式就是物理寻址(physical addressing)
    • 大于一个字节的数据类型会被连续的存储在多个内存地址中,任然只用一个地址来寻址
    • 每个位置有独一无二的地址用来寻址
    • 每个地址都存放了一个值

      体系结构,深入理解计算机操作系统,第九章,虚拟内存

  • 指针

    编译原理

    • 指针:存储了另一个“内存地址”的变量
      • 首先,指针是一个变量,同样可以使用变量类型修饰符,(变量在编程语言的层面表示:程序可以操作的内存地址空间的“名称”,名称只在编程语言中有实际意义,在编译器中会进行相应的分析和链接处理,最终转为机器码;)
      • 指针存放了,另一个段内存地址的“地址编号”
      • 指向:表示指针存储的“内存地址”,经过寻址后找到的存储在该“内存地址中的” 值
    • & 取地址运算符 *间接访问运算符/解引用运算符
      • & 用来取得任何变量当前的地址
      • 对一个指针变量取地址后,得到的是该指针变量自己的地址
      • * 的第一个作用是,声明,表示声明的变量类型为“某种指针类型”,如int指针类型,char指针类型,等(指针基类type)
      • * 的第二个作用是,间接访问,可以通过在变量前面加* 表示,获取该指针指向的“值”
      • 指针变量自己的值同样为一个 无符号整数(内存地址的16进程表示)
    • 声明、定义、赋值
      • 使用 类型 + * + 变量名称 进行声明
      • 变量名称 = <某个地址> 来进行定义,指针的类型会被绑定到指向的值的类型
      • 只有同样的类型的地址才能赋值
      • 创建指针对象的过程中,并不会在内存上开辟空间来进行初始化,指针变量初始地址为一个随机地址;
      • 声明指针对象的同时不能直接赋值,对于未分配内存空间的指针变量,值无处存放;
      • 声明指针对象的同时定义,必须赋值一个内存地址;

        warning: initialization makes pointer from integer without a cast

    • 解引用,脱去解引用

      & 在C/C++中具体 3种语义, 按位与,取地址 和 声明一个引用。

      • int a = 999; int * b = &a; * b = 0; 解引用,解释引用,表示将指针变量保存的内存地址中存储的999修改为了0
      • &*b 获取a的地址,脱去了解引用
    • 指针运算

      算数运算和关系运算

    • NULL指针
      • 直接给指针赋值0或者NULL int * p = 0; int * p = NULL;
      • NULL指针不指向任何地方,所以无法解引用
    • 指针的指针
      • 指向指针变量的指针变量(指向指针对象的指针对象)
#include <stdio.h>


int main() {

	int a = 100;
	int * b = &a; //声明了一个变量类型为type的类型(因为指针的基类型就是type)
	//b = &a;  // 这里对已经声明的指针类型b,进行了定义,将其定义为了 整型指针类型

	printf("%p\n", &a);		// 取地址,取地存放a内存地址,也就是存放整数100的地址段
	printf("%p\n", b);		// 取地址,由于指针变量本身就存储了它指向的地址段,所以使用取地址符打印指针变量的值,就会打印出它存放的指针地址
	printf("%p\n", &b);		// 取该指针变量自己的地址

	printf("%d\n", a);
	printf("%d\n", *b);		// * 为间接访问运算符,通过在指针便变量前面加*,可以间接的访问该指针指向的值


	// char * c = (char *)&a;

	// printf("%d\n", *b);

	// printf("%d\n", *c);

	char s = 'f';
	char * p1 = &s;
	char ** p2 = &p1;

	printf("%c\n", s);
	printf("%c\n", * p1);
	printf("%p\n", * p2);
	printf("%c\n", ** p2);


	printf("%p\n", &s);
	printf("%p\n", p1);
	printf("%p\n", &p1);
	printf("%p\n", p2);
	printf("%p\n", &p2);

	return 0;
}

C++ 指针、引用&

  • 指针
    • 空指针 nullptr int * p = nullptr

      解引用没有初始化的指针发送错误 定义了对象之后再定义指向这个对象的指针,对于不清楚的指向哪里的指针,一律初始化为nullptr(C++11)或者NULL(0).之后再判断是否指向对象再进行相应的操作.

C 中的 &

  • C的标准中对于运算符 & 出现在变量前,表示的是取地址符
  • 取地址符,可以取得任何变量当前在虚拟内存中的地址

C++ 引入的新特性“引用”

  • 引用,对于目标一个变量的一个别名,使用引用对变量的操作和对变量的直接操作是完全一样的;
  • 引用使用 & 进行声明
    • 类型标示符 &引用名 = 目标变量名
    • 在这个声明中,使用&符号对目标变量声明了一个新的名字,而这个名字代表的就是目标变量的值;
    • 【&】在这个变量声明中不是一个取地址符,而是起到标示作用,用来声明当前是一个引用声明,类似于指针类型的声明,需要加 也是在当前声明中来声明这是个指针相关的类型声明;
    • 【类型标示符】是目标变量的类型;
    • 声明引用的同时,必须完成其初始化;
    • 完成了引用声明之后,相当于该变量有两个名称,用这两名称都可以直接访问变量,即该变量的原名和引用名,这时候该引用名属于该变量,不能再将该引用名作为其他变量名的别名(不能再做其他变量的引用);

    https://blog.csdn.net/weixin_44023607/article/details/104235331

    TODO


Back to top

Engineering & Philosophy & Life Experience - A Motorcycle rider and loving husband.