指针
在64系统环境下,所有指针都是8个字节
地址是常量
指针是变量,是地址的变量
只有变量有地址,常量没有地址。
因为常量本质上是内存上的空间,常量不是空间,所以常量没有地址。
指针是一种保存变量地址的变量
指针类型可由 函数类型 对象类型 或 不完全的类型派生
派生指针类型的类型 称为 引用类型
指针类型描述一个对象,该类对象的值提供对该引用类型实体的引用
由引用类型T派生的指针类型 有时称为 (指向)T的指针
int类型 float类型 double类型 指针类型
由引用类型T派生的指针类型 有时 称为 指向T的指针
实际上存在的类型
指向int的指针类型 指向float的指针类型
存在 指针类型 指针类型变量 指针类型的值
但是通常被简单地统称为 指针 —bug
先有 指针类型 再有 指针类型的变量 指针类型的值
int 类型 存在保存int类型的变量 也存在int类型的值
对变量使用&运算符,可以取得该变量的地址。这个地址称为指向该变量的指针
指针变量*hoge_P保存了指向hope地址的情况下
可以说hoge_p指向hoge,*hoge_p就是hoge
声明 类型 类型名
int hope_p (int hope_p)
int *hope_p
理解为*hope_p可以和hope同等使用
指针类型的值 实际是 内存的地址
指针就是地址 地址就是内存中被分配的 门牌号
对指针加N,指针前进 当前指针指向的数据类型的长度XN
int *p=3 会出现警示 因为3无论如何都是int型
int *p=0不会出现警示,因为 当常量0处于应该作为指针使用的上下文时,它就应该作为空指针使用
数组与指针
指针是地址变量,数组名是地址常量
int hoge[10]可以解读成&hoge[0]。
&将一个左值作为操作数,返回指向该左值的指针。
地址运算符不能将非左值的表达式作为操作数。
p[i]就是*(p+1)的语法糖,除此之外没有任何意义
p->hogs 是 (*p).hogs的语法糖
int a[10];
a[0] = 10;
a[1] = 20;
//单独的数组名a相当于第一个元素的地址,即&a[0]
cout << *a ; // 10
//指针变量+1,相当于加1个其指向的字节
//将5强制转换为指针变量
int*c = (int*)5;
c++; //c = 9;p指向int,所以+4
int *b = a;
cout << *++b; // 20
指向函数的指针
int func(double a);
//保存指向此函数的指针的变量申明如下
//func本身就是函数指针变量,而func_p也是函数指针变量
int (*func_p)(double);
func_p = func;
//此时func_p = func
func_p(0.5);
数组函数形参
c中是不能将数组作为函数参数进行传递,那就传递指向初始元素的指针
在c中,函数参数传递都是传值,向函数传递的都是参数的副本
传递数组也是传递指向数组初始元素的指针的副本.
如果对所有数组一一赋值,那将是非常耗时的
无论如何都要将数组进行值传递的时候,建议将数组整体整理成结构体
只有在申明形参时,数组的申明才可以被解读成指针
int func(int* a)
int func(int a[])
int func(int a[10])
具有相同的意义
多维数组
其实是数组的数组
对于函数的形参,最外层的数组会被解读成指针,即使定义了元素个数也会被无视。
编译器可以根据初始化表达式确定元素个数。所以省略最外层元素的个数。
int[][6] 第一个[]标示最外层。
在初始化不对整的数组时,没有赋值的初始化为0
数组遍历优化
for(int I=0;i<10;i++)
Array[i]
Array [i]在循环中会出现多次,每次都要进行相当于*(array+i)的加法运算,效率自然比较低
p=&array[0] p!=&array[] p++