指针
指针的应用场景
1.函数返回值是多个,可通过指针返回
在函数内,如果传入两个数的值,在函数内可以交换两个数的值,但出了函数的作用域外,则不生效;如果此时传入的是两个数的地址,那么出了函数作用域外,两个数的值也是交换了的。
- 函数返回多个值,某些值就只能通过指针返回
- 传入的参数 实际上是需要保存带回结果的变量
2.函数返回运算的状态,结果通过指针返回
做两数相除,返回值返回运算状态(是否有结果或者是够出错),运算结果通过指针参数返回。
- 如果函数计算需要返回运算的状态 以及 结果,就需函数返回值返回相应状态,具体结果通过指针参数返回
常见使用错误
定义了指针变量,还没有指向任何变量,就开始使用指针。
指针与数组
函数参数表中的数组 是指针 ;
数组变量是特殊的指针;
数组变量本身表达地址,所以
- int a[10]; int *p = a; 无需用&取地址
- 但是数组的单元表达的是变量,需要用&取地址 a==&a[0]
- []运算符可以对数组做,也可以对指针做:p[0]<==> a[0]
- *运算符可以最指针做,也可以对数组做
- 数组变量是const的指针,所以不能被赋值。
指针与const
指针可以是const, 指针的值也可以是const
当指针是const
- 表示一旦得到了某个变量的地址,不能再指向其他变量
- int *const q = &i;// q 是const
- *q = 26; // ok
- q++; // error
当所指的值是const
- 表示不能通过这个指针去修改那个变量(并不能使得那个变量成为const)
- const int *p = &i;
- 星p = 26; //error! (*p是const)
- i = 26; //ok
- p = &j; //ok
const位置 (判断哪个被const了的标志是,const是在的前面还是后面);
const在的前面表示所指的东西不能修改(下面1和2一样)
const在*的后面表示指针不能被修改
- const int* p1 = &i;
- int const* p1 = &i;
- int *const p1 = &i;
const数组
const int a[] = {1,2,3,4,5};
数组变量已经是const的指针了,这里的const表明数组的每个单元都是const int
所以必须通过初始化进行赋值
保护数组值
- 因为把数组传入函数的时候传递的是地址,所以函数内部可以修改数组的值
- 为了保护数组不被函数破坏,可以设置参数为const
- int sum (const int a[],int length);
指针运算
- (p+n) <=> a[n]; // 等价的
- 两个指针相减 结果不是 两个地址的差 而是两个地址的差除以sizeof(p)的值,代表这两个地址之间可以放几个这样的值
*p++
- 取出p所指的那个数据,然后顺便把p移到下一个位置去;
- *的优先级虽然高,但没有++高(先算p++,但++为后缀,其值与p相同,注意与++p的差异)
- 常用于数组类的连续空间操作
- 在某些CPU上,这可以直接被翻译成一条汇编指令
指针比较
- <,<=,==,>,>=,!= 都可以对指针做
- 比较它们在内存中的地址
- 数组中的单元的地址肯定是线性递增的
0地址
- 0地址通常是个不能随便碰的地址
- 所以指针不应该具有0值
- 因此可以用0地址来表示特殊的事情
- 返回的指针是无效的
- 指针没有被真正的初始化(先初始化为0)
- NULL是一个预定义的符号,表示0地址
指针的类型
- 无论指向什么类型,所有的指针大小都是一样的,因为都是地址
- 但是指向不同类型的指针是不能直接相互赋值的
- 这是为了避免用错指针
指针的类型转换
- void* 表示不知道指向什么东西的指针
- 计算时与char*相同(但不相通)
- 指针也可以转换类型
- int * p = &i; void * q = (void *)p;
- 这并没有改变p所指的变量的类型,而是让后人用不同的眼光通过p看它所指的变量(通过p看i是int,通过q看i则是void)
- 我不再当你是int啦,我认为你就是一个void!
用指针可以做什么
- 需要传入较大的数据时用作参数(如数组)
- 传入数组后对数组做操作
- 函数返回值不止一个结果
- 需要用行数来修改不止一个变量
- 动态申请内存
网友评论