指针
int * &c = a;//这里c是一个引用,它是指针a的引用
int & *d;//这里d是一个指针,它指向引用,但引用不是实体,所以这是错误的
int* const p 特点是指针指向的数值可以改变,然而指针所保存的地址却不可以改变
const int* p 特点是指针所保存的地址可以改变,然而指针所指向的值却不可以改变
int const* p 特点是指针所保存的地址可以改变,然而指针所指向的值却不可以改变
const int* const p 特点是指针所保存的地址不可以改变,指针所指向的值不可以改变
指针函数是指带指针的函数,即本质是一个函数。函数返回类型是某一类型的指针
类型标识符 *函数名(参数表)
int *f(x,y);
首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,
而且,在主调函数中,函数返回值必须赋给同类型的指针变量。
函数指针是指向函数的指针变量,即本质是一个指针变量。
int (*f) (int x); /* 声明一个函数指针 */
f=func; /* 将func函数的首地址赋给指针f */
指向函数的指针包含了函数的地址,可以通过它来调用函数。声明格式如下:
类型说明符 (*函数名)(参数)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void (*funcp)(); void FileFunc(),EditFunc(); void FileFunc() { printf("FileFunc\n"); } void EditFunc() { printf("EditFunc\n"); } int _tmain(int argc, _TCHAR* argv[]) { funcp=FileFunc; (*funcp)(); funcp=EditFunc; funcp();
优先级:
1) ()>[]>*
2) 右++ > * > 左++ *p++ == *(p++) ++*p == ++(*p)
数组指针(也称行指针)
定义 int (*p)[n];
()优先级高,说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。
指针数组
定义 int *p[n];
[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; int main ( ) { char *str[]={"welcome","to","fortemedia","Nanjing"}; char * * p=str+1; //p指向 "to"字符串地址 str[0]=(*p++) +2; //str[0]指向'\0'; 然后p后移 p=str[2] str[1]=*(p+1); //p+1后 p+1 = str[3]; 然后 str[1] = str[3] str[2]=p[1]+3; //str[2]指向str[3]的从0开始数的第三个 str[2]指向"jing"地址 str[3]=p[0]+(str[2]-str[1]); //str[3]指向从p[0]开始(也就是*p,也就是str[2])的 偏移量为(str[2]-str[1])的地址~ str[2]指向"jing",str[1]指向str[3],也就是"Namjing",所以str[3]指向"jing"的"g"地址 printf("%s\n",str[0]); printf("%s\n",str[1]); printf("%s\n",str[2]); printf("%s\n",str[3]); return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int main() { char *str[] = {"Welcome","to","Fortemedia","Nanjing"}; char **p = str + 1; str[0] = *p++; //{"to","to","Fortemedia","Nanjing"}; str[1] = *(p+1); //{"to","Nanjing","Fortemedia","Nanjing"}; str[2] = p[1] + 3; //{"to","Nanjing","jing","Nanjing"}; str[3] = p[0] + (str[2] - str[1]); //str[2]-str[1]是原来的指向Nanjing中的j的指针减去Nanjing中的N的指针,当然是3了 //p[0] 是指向"jing"中的j的,再加3就是g了 printf("%s\n",str[0]); printf("%s\n",str[1]); printf("%s\n",str[2]); printf("%s\n",str[3]); return 0; }
1) this指针的用处:
一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。 例如,调用date.SetMonth(9) <===> SetMonth(&date, 9),this帮助完成了这一转换 .
2) this指针的使用:
一种情况就是,在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this;另外一种情况是当参数与成员变量名相同时,如this->n = n (不能写成n = n)。
3) this指针程序示例:
this指针存在于类的成员函数中,指向被调用函数所在的类实例的地址
1) this只能在成员函数中使用。
2) this在成员函数的开始前构造,在成员函数的结束后清除
3) this指针会因编译器不同而有不同的放置位置。可能是栈,也可能是寄存器,甚至全局变量
4) 大多数编译器通过ecx寄存器传递this指针
结构体偏移量
offset = (unsigned long)(&((type*)0))->member); 其中type就是结构体类型,member即某字段名。
#define STRUCT_FIELD(address, type, field) ((type *)((char*)(address) + (size_t)(&((type *)0)->field)))
#define FIELD_STRUCT(address, type, field) ((type *)((char*)(address) - (size_t)(&((type *)0)->field)))