c++ 中sizeof 与数组形参
sizeof,返回表达式或类型名所占用的字节数。
int x[10];
int* p = x;
cout << sizeof(x) << endl; //40,结果为数组占用的总空间
cout << sizeof(*x) << endl; //4,结果为数组类型占用的空间
cout << sizeof(p) << endl; //4,结果为指针占用的空间
cout << sizeof(*p) << endl; //4,结果为int占用的空间
cout << sizeof(x) / sizeof(*x) << endl; //10
cout << sizeof(p) / sizeof(*p) << endl; //1
数组两大特殊性质:
- 不允许拷贝数组。
- 使用数组时通常会将数组转换为指针。
所以,当数组作为函数形参时,由于性质1,无法进行值传递,所以实际上传入的是指向数组首元素的指针。举个粒子,如下函数:
void func(int* arr){
int length = sizeof(arr)/sizeof(*arr);
cout<<length<<endl;
}
int main(){
int arr[6] = {9,1,1,2,3,7};
func(arr);
}
我们将会看到,输出结果为1,因为我们的实参根据性质2转换成指针了,sizeof分别对指针和指针指向类型int运算,而上面我们知道他们得出的结果分别是4/4,所以我们并没有得到数组的长度。
C++允许将形参定义成数组的引用,将形参作为数组的引用。
int length(const int(&arr)[6]) {
int length = sizeof(arr) / sizeof(int);
return length;
}
int main(){
int arr[6] = {1,1,2,3,7};
int index = length(arr);
cout << "index: " << index2 << endl;;
}
这样就可以传入数组实参,在函数中获得数组的长度了,但实际上这操作太蠢了,因为数组的大小我们也要同时传入,这带来极大不便,所以我们可以使用另一种方法:非类型模板参数。
非类型模板参数,当编译器实例化模板时,编译器可以推断出该参数值,绑定到此参数值的实参必须为常量表达式。写个二分模板如下:
template<typename _Ty,size_t Size>
int binary(const _Ty (&arr)[Size],_Ty target) {
_Ty left = 0;
_Ty right = sizeof(arr) / sizeof(_Ty) - 1;
/*int mid = 0;*/
while (left <= right) {
_Ty mid = left + (right - left) / 2;
if (arr[mid] == target) {
cout<< "mid"<<mid <<endl;
return mid;
}
else if (arr[mid] < target) {
left = mid + 1;
}
else if (arr[mid] > target) {
right = mid - 1;
}
}
return -1;
}
|