指针相信都比较熟悉了,这里稍微总结一下。
1、传递参数给函数
在c++,中,有三种方式可以将参数传递给函数,前面已经讨论过了两个:传值调用和按引用调用,还有一种情况就是使用“指针参数按引用调用”,听起来比较拗口,下面来举一下例子
using std::cout;
using std::endl;
int cubeByValue(int);
void cubeByReference(int &);
void cubeByPointer(int *);
int main()
...{
int n1 = 1, n2 = 1, n3 =1;
n1 = cubeByValue(n1);
cubeByReference(n2);
cubeByPointer(&n3);
cout << n1 << ' '<< n2 << ' ' << n3 << endl;
}
int cubeByValue( int i)//传值调用
...{
return i*2;
}
void cubeByReference(int & i)//引用调用
...{
i *= 2;
}
void cubeByPointer(int* i)//使用指针参数按引用调用
...{
*i = ( *i) * 2;
}
/**//*输出结果
2 2 2
*/
2、用const限定访问权限
使用const,我们可以有4种方法将指针传递给函数,当然,这代表了4种不同的访问权限:
a) 非常量数据的非常量指针。拥有最高权限,数据可以通过复引用指针来修改,同时指针也可以修改为指向其他数据。次指针的声明中不包含const限定符。
b)常量数据的非常量指针。指针可以被修改为指向其他数据,但是被指向的数据不能通过复引用指针来修改。这种指针通常作为打印数组的函数的数组参数。
...{
for(;*sPtr != '/0';sPtr++)
c)非常量数据的常量指针。指针总是指向相同的内存地址,但可以修改这个地址里的数据内容。例如数组名就是非常量数据的常量指针。
d)常量数据的常量指针。这里有最低权限,当数组被传递到函数,并且函数不能修改数组内容时,就是这种情况。
...{
int x = 5;
const int * const ptr = & x;
//*ptr = 7 //错!
// ptr ++ //错!
}
3、数组的sizeof结果
当sizeof用在一个数组身上,那么返回的是这个数组所占用的总字节数,当数组被转换为指针参数时,sizeof将返回指针的长度(通常为4),而不是数组长度。
...{
return sizeof(ptr);
}
int main()
...{
double array[20];
cout << sizeof(array)<<endl<<getSize(array)<<endl;
cout << sizeof(array) / sizeof(double);//当知道数组里面的数据类型时,可以用此方法得到数组长度
}
/**//*输出
80
4
20
*/
(注:sizeof是一个操作符,而不是一个函数,使用sizeof不会对程序性能产生不良影响。sizeof返回类型是size_t 通常被定义为unsigned int类型。)
4、指针表达式和指针算法
指针可以自增、自减、加减一个整数、减一个指针。
a)指针加减一个整数 i 是把它所指向的位置加上 i * (它所指向的数据类型),即如果一个指向int类型的指针变量ptr所指向的内存位置是100,那么 prt++ 后,它所指向的内存地址是100 + 1*sizeof( int ) = 104;
b)不是任意两个指针都可以进行相互的减操作,只有两个指针都指向一个数组里面的数据时才能进行减操作。得到的结果是两个指针之间的元素个数。
c)将一个指针赋值给另一个指针时,语句左右两边的类型必须一致,不一致也必须用强制转换来换成一致。这里有一个例外,就是void *类型,它是一个通用指针,任何指针都可以不通过强制转换赋值给void *类型的指针,相反,void *类型的指针必须经过强制转换后才能赋值给其他类型的指针。并且void *类型的指针不能被复引用,因为编译器不知道指针指向的数据类型。综合例子:
...{
int array[4];
double *dbPtr;
void *vd;
int *ptr1 = array;
int *ptr2 = &array[0];
ptr1++;//此时ptr1指向元素array[1]
ptr2 += 3;//此时ptr2指向元素array[3]
cout << ptr2 - ptr1<<endl;//相减得到两个指针之间元素的个数
dbPtr = (double *)ptr1;//必须经过强制类型转换
vd = dbPtr;//不需要强制类型转换
ptr2 = (int *) vd;//必须经过强制类型转换
return 1;
}
/**//*输出
2
*/
5、函数指针
函数指针指向函数在内存中的地址。函数名其实就是执行这个函数任务的代码在内存中的开始地址。函数指针能够传递给函数、能够从函数返回、能够放在数组中以及能够赋值给其他函数指针。