一、引言
C语言用久了,今天看到C++的cin用法,突然觉得很有问题,例如:
char ch;
cin>>ch;
cin.get(ch);
按照C语言风格,应该用的是地址或者指针:
cin>>&ch; //写法不一定正确
get(&ch); //写法不一定正确
否则,就像函数get(ch),参数是按值传递,函数内部无法修改ch的值。
为什么C++可以这样使用呢? 查了查资料以后,才知道,这是C++新引入的 “参数引用”。查看get()函数的原型为: istream& get ( char& c );
二、代码验证
下面用代码验证一下参数引用。
1、在C语言中,如下代码:
void changeVal(int &data) //error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token
{
data = 100;
}
用gcc编译不通过error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token。 可知C语言不支持参数引用。(或者说至少是我的gcc编译器4.4.4不支持)
下面我们看下按值传递
void changeVal(int data)
{
printf("the address of data is %p \n", &data); //the address of data is 0xbfc91960
data = 100;
}
int main(int argc, char *argv[])
{
int data = 10;
printf("the address of data is %p \n", &data); //the address of data is 0xbfc9197c
changeVal(data);
printf("data = %d \n", data); //10
return 0;
}
按值传递,传入函数的只是data的一个副本(两处地址不一样)
2、C++语言
void changeVal(int &data)
{
cout<<"the address of data is "<<&data<<endl; //the address of data is 0xbfa6b33c
data = 100;
}
int main(int argc, char *argv[])
{
int data = 10;
cout<<"the address of data is "<<&data<<endl; //the address of data is 0xbfa6b33c
changeVal(data);
cout<<"data = "<<data<<endl; //data = 100
return 0;
}
可以看出,参数引用传入的就是data参数,并不是其副本。
三、cin>>, cin.get(ch)的几种用法
经过上面的代码对比后,我想可不可以用C语言的风格来使用cin呢?
char data = 'a';
cin>>data;
cin>>&data; //居然可以?
cin.get(data);
//cin.get(&data); //error: no matching function for call to ‘std::basic_istream<char, std::char_traits<char> >::get(char*)’
观察下上面代码, 什么?cin>>&data;居然可以??? 如果将data改成int类型会如何呢?
int data = 10;
cin>>data;
cin>>&data; //error: no match for ‘operator>>’ in ‘std::cin >> & data’
为什么char类型的可以,int不行呢? 这就涉及到cin的识别问题。 如果传入的是(char *)&data,则cin会将这个地址当成字符串的开始地址。上面的int类型,强转后,就可以通过编译
int data = 10;
cin>>data;
cin>>(char*)&data; //编译通过
下面我们通过代码验证一下cin是否将cin>>(char*)&data;识别成了字符串。
char data = 'a';
cin>>&data;
cout<<"data = "<<&data<<endl;
编译执行该段代码:
./parameter
hello
data = hello
通过上述代码,cin>>&data,确实将&data当成了字符串首地址。