目录
指针
指针是变量的地址,可以用C ++访问。
int a = 54;
54 是变量的值,换句话说,它是存储在称为 "a" 的变量保留的位置中的值。
现在,让我们问自己,在哪里? "a" 的位置可以使用指针找到!
int a = 54;
std::cout<< &a<<"\n"; //This will print the LOCATION of 'a'
有关指针的更多信息,请点击:Pointers
运行以下代码:
#include <iostream>
int main()
{
int a = 54;
std::cout<<"a = "<<a<<"\n";
std::cout<<"address of a is at &a = "<< &a<<"\n";
return 0;
}
结果:
指针取值
但如果 我们有一个指针 并 想要访问存储在该地址中的值呢? 该过程称为 指针取值(Dereferencing Pointers),并通过在变量名称前 添加运算符 * 来指示。 应该使用相同的运算符 来声明 用于存储指针的变量。
看一个简短程序,可以大概了解其使用:
// this is an integer variable with value = 54
int a = 54;
// 这个指针pointerToA 保存(指向) 变量a的地址。
// if 'a' was a float, rather than int, so should be its pointer.
int * pointerToA = &a;
// 如果我们要打印 pointerToA ,我们将获得 'a' 的地址:
std::cout << "pointerToA stores " << pointerToA << '\n';
// 如果我们想知道这个地址中存储了什么,我们可以取指针pointerToA的值:
std::cout << "pointerToA points to " << * pointerToA << '\n';
// 我们打印&pointerToA指针变量的内存地址
std::cout << "pointerToA address " << &pointerToA << "\n";
代码解析:
1、
int * pointerToA = &a;
怎么解读这个指针语句?
答:在内存申请一个四个字节(整型)内存的 指针变量pointerToA (注意:pointerToA这个指针变量有自己的内存地址),然后指向 整型变量a 的地址,所以,指针变量pointerToA 现在的地址是 整型变量a 的地址。
2、
std::cout << "pointerToA address " << &pointerToA << "\n";
我们打印 指针变量的&pointerToA,也就是它的内存地址,是否跟 整型变量a 一样呢?
答:肯定不一样。因为 指针变量pointerToA 有自己的内存地址。
3、
现在 指针变量pointerToA 的值肯定是54,那么如果我们改变 指针变量 pointerToA 的值的话,整型变量a 的值会不会跟着改变?
答:是会的。如果 指针变量 pointerToA 的值改为8,那么 整型变量a 也会变成 8。
举例:
#include<iostream>
#include<string>
int main()
{
std::string name;
int givenInt;
float givenFloat;
double givenDouble;
std::string givenString;
char givenChar;
int *pointerGivenInt;
int **pointerPointerGivenInt;
pointerGivenInt = &givenInt;
pointerPointerGivenInt = &pointerGivenInt;
//Get the values of each variable
std::cout<<"integer = \n";
std::cin>>givenInt;
std::cout<<"float = \n";
std::cin>>givenFloat;
std::cout<<"double = \n";
std::cin>>givenDouble;
//We need to use cin.ignore so cin will ignore
//the characters in the buffer leftover
//from the givenDouble
std::cin.ignore();
std::cout<<"character = \n";
std::cin>>givenChar;
std::cout<<"string = \n";
std::cin.ignore();
std::getline (std::cin,givenString);
//The value stored in the data
std::cout<<"integer = "<<givenInt<<"\n";
std::cout<<"float = "<<givenFloat<<"\n";
std::cout<<"double = "<<givenDouble<<"\n";
std::cout<<"string = "<<givenString<<"\n";
std::cout<<"character = "<<(char)givenChar<<"\n\n";
//The address of the data - use pointers
std::cout<<"address integer = "<<&givenInt<<"\n";
std::cout<<"address float = "<<&givenFloat<<"\n";
std::cout<<"address double = "<<&givenDouble<<"\n";
std::cout<<"address string = "<<&givenString<<"\n";
std::cout<< "address character = " << (void *) &givenChar<<"\n\n";
//Use indirection to the get the value stored at the address
std::cout<< "pointer of givenInt = " << *pointerGivenInt<<"\n";
std::cout<< "pointer of pointer of givenInt = " << **pointerPointerGivenInt<< "\n";
return 0;
}
运行结果:
以上代码的技术解析:
1。代码:int **pointerPointerGivenInt; 这里面的 " ** " 双星号是什么意思呢?
答:表示定义一个 int 类型的二级指针。二级指针表示 指针指向的内存单元中存放的仍然是一个指针,所以需要两次转换才能得到改二级指针指向的数据。
举例:
#include<iostream>
#include<string>
int main()
{
double a = 6.65;
double *b = &a;
double **c = &b;
std::cout<<**c;
return 0;
}
输出:
a 是一个 double类型的变量,值为6.65,
b 是一个指针变量,指向 a 这个 double类型 的数据,
c 是一个指针变量,指向 b 这个 double * 类型的数据,即指向指针的指针;最后打印 **c 打印出来还是6.65。
2。代码:std::cin.ignore(); 这代码是什么意思? ignore() 是什么?
答:首先我要知道一个什么是缓冲区?缓冲区(buffer),它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区,显然缓冲区是具有一定大小的。
cin.sync()这个函数是清空缓冲区,而 cin.ignore() 虽然也是清空缓冲区中数据的作用,但其对缓冲区中的删除数据控制的较精确。
举例:
#include <iostream>
using namespace std;
int main()
{
char str[30];
cout << "请输入一个字符串:";
cin >> str;
cout << str << endl;
cout << "请输入任意字符结束程序!\n";
cin.get();
return 0;
}
注意以上代码,输入一个字符串,然后使用 cin.get(); 再次输入字符串,我们运行代码:
发现个问题,程序没有让我再输入字符串就直接退出了!!!怎么会这样?C++有问题?不是的。
我们先来学习一下 cin.get(),有一个特性,cin.get() 作为第二次输入时,接收到 回车 或 空格 或 制表符 就会停止输入的。
所以,当我输入一个字符串时候,我输入 a 然后 回车 '\n',这里输入回车('\n')已经被 cin.get() 接收了,所以退出了。
这个问题怎么解决? 我还是想输入两次字符再退出。cin.ignore() 出场了。
修改后的代码:
#include <iostream>
using namespace std;
int main()
{
char str[30];
cout << "请输入一个字符串:";
cin >> str;
cout << str << endl;
cin.ignore(100, '\n');
cout << "请输入任意字符结束程序!\n";
cin.get();
return 0;
}
运行结果:
终于可以输入两次了,cin.ignore() 为什么会起作用?我们学习一下 cin.ignore(100,'\n');
cin.ignore(int intExp, char chExp),这里 int intExp 表示要忽略的字符长度,这里 char chExp 表示要忽略的字符串。
举例:
#include<iostream>
#include<cstdlib>
int main()
{
int ival1 = 0, ival2 = 0;
std::cin >> ival1;
std::cin.ignore(100, '\n');
std::cin >> ival2;
std::cout << "ival1 = " << ival1 << std::endl;
std::cout << "ival2 = " << ival2 << std::endl;
system("pause");
return 0;
}
运行结果:
当我们输入1 2 的时候,输入回车,它就能够继续执行用户输入,因为 cin.ignore(100,'\n'); 忽略回车键,然后把输入数字1 后面的100个字符忽略,所以,ival1才等于1。
我们注释 cin.ignore(); 来看看效果:
#include<iostream>
#include<cstdlib>
int main()
{
int ival1 = 0, ival2 = 0;
std::cin >> ival1;
// std::cin.ignore(100, '\n');
std::cin >> ival2;
std::cout << "ival1 = " << ival1 << std::endl;
std::cout << "ival2 = " << ival2 << std::endl;
system("pause");
return 0;
}
运行结果:
没有 cin.ignore(); 就不会让你输入第二次了。它就直接把 1 后面 空格的 2赋值给 ival2 。
一个拓展例子,请自行学习:
#include<iostream>
#include<string>
int main ()
{
int * pointerI;
int number;
char character;
char * pointerC;
std::string sentence;
std::string *pointerS;
pointerI = &number;
*pointerI = 45;
pointerC = &character;
*pointerC = 'f';
pointerS = &sentence;
*pointerS = "Hey look at me, I know pointers!";
std::cout << "number = "<<number<<"\n";
std::cout<<"character = "<<character<<"\n";
std::cout<<"sentence = "<<sentence<<"\n";
return 0;
}
运行结果:
当你还不能写出自己满意的程序时,你就不要去睡觉。