在小编这里,没有任何学习知识的顺序,写到的东西对初学者肯定是有用处的,前提,你真的把C语言学完的那些初学者。
在讲明指针的知识前,或许有人一直说不会指针你学不会C++,或者说你所学C++的深度,全凭你所了解指针用法的多少。
那么,在小编这里请你删除那些言论。
我们一直追求一个知识点的时候,只是跟风般的去学,根本不知道为何要用到知识点,如何用?
下面的一些话有的是找到的,也有自己的见解:
一个数据类型的变量名,可以说是跟内存地址挂钩的,只要是变量它都有一个单独的内存地址,可能因为某些原因,想精确的找到内存地址上存储的数据,因此用到指针这一特殊访问内存的机制,对内存进行直接操作。
对于指针的知识点,全靠你敲代码,看规律,找规律,自己总结出一套属于自己的见解,你就离学会指针不远了。
指针,就是一个地址,不管哪个类型的变量,你就把它看作是一个地址,存储数据的地址。对于编译器而言,它找对了地址就自然能将数据找到。
#include <iostream> using namespace std; int main() { int number = 0; //声明定义number初始化为0 int *p = NULL; //声明定义指针p初始化为空 p = &number; //&number 将number的地址赋值给地址p cout << *p << endl; //打印*p,即首地址的值 system("pause"); return 0; }
能看出什么?变量和地址,它们之间的关系并不复杂,关键你能把地址、变量先分开看清楚。地址跟地址,变量跟变量。
看运行结果:0,即number的初始化值。
或许有人会问为什么打印地址不能将数值打印出来,小编的见解很简单:一段路程,只知道起点,走出了第一步时你只知道起点,你根本不知道终点与起点的距离(元素数据),当你走过一段后,路程距离多少你根本不知道,回头一看一想,只知道起点在哪。
那么指针地址也一样的,不管地址内摆放什么东西(路程的距离),当你找到此地址时(路程),你只知道首地址(起点地址)。
为什么加上*号,你就看作是记忆那印记,没有想到那点印记时,你就不会想到那个起点在哪。通俗的讲就是:一个印记代表一个起点,你知道了哪个印记,就知道那个起点在哪。
而编译器呢?她将起点按逻辑数字一个个串起来的,数字累加起来的,你找到哪个数字,就能找到数字地址上的数据。
指针,它按数据类型的
看下面:
#include <iostream> using namespace std; int main() { char str[] = "helloworld!"; char *p = str; //str本身就是地址,所以一级指针不需要加& cout << *p << endl; //cout << *(p + 0) << endl; cout << *(p + 1); cout << *(p + 2); cout << *(p + 3); cout << *(p + 4); cout << *(p + 5); cout << *(p + 6); cout << *(p + 7); cout << *(p + 8); cout << *(p + 9); cout << *(p + 10);
cout << *(p + 11); system("pause"); return 0; }
运行的结果:helloworld!
那么怎么才能分辨哪个地址对应哪个数据呢?这个其实没必要管,因为编译器知道,你只要将地址告诉编译器,她能找到数据,毕竟这属于初学者需要了解的。
记住:指针地址永远同等为地址的数据对接,简而言之,地址=地址,变量=变量。
深入了解下,为什么改变了首地址值时,对原来的数据有影响呢?
#include <iostream> using namespace std; int main() { int number = 123; int *p = &number; //地址=地址,p就是number的地址,p指向number *p = 321; //看作是*(p+0)=321,*(p+0)是谁的地址?number cout << number << endl; system("pause"); return 0; }
按道理说,改变了一个*p时,跟原来的number没有关系才对,可是还是对原来的number值做出改变。为什么?
前面说过:地址=地址,变量=变量;那么当p=&number,没错,意思就是p为123的地址,当*p=321,没错,意思就是这个地址不变,里面的数据变了,为321;那个变了的数据是什么?赋值的number
简而言之:p它是地址没错,谁的地址?int *p 设定为NULL的地址,当p=&number时,即p指向number的地址;当*p=321时,即*(p+0)=321(number为321);不管*p怎么改变,地址没有变,变得是number,
这只是小编的理解。有点复杂,看不懂的也没关系,你只要知道:将变量以地址方式给一个地址,改变了首地址值时,对原来的数据有影响。
看完上面的内容, 是不是感觉有点懂呢?看看下面的,看看你能否看懂:
#include <iostream> using namespace std; int main() { for (int i = 1;i < 10;i++) { int number= 1; //每次循环后number被带入时它都为1 for (int *p =&number ;*p <=i;(*p)++) {
/*
*p=1; 1<=1符合条件; (*p)++,即number++ 循环一次
1*1=1
*p=1; 1<=2; (*)p++,number++ 循环两次
1*2=2 2*2=4
*p=1; 1<=3; (*)p++,number++ 循环三次
1*3=3 2*3=6 3*3=9
以此类推
1*4=4 2*4=8 3*4=12 4*4=16 循环四次
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 循环五次
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 循环六次
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 循环七次
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 循环八次
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 循环九次
*/ cout << *p << "*" << i << "=" << (*p)*i << "\t"; } cout << endl; } system("pause"); return 0; }
看看运行结果,这是一个九九乘法表。这个看不懂没关系,可以肯定的告诉你,你也会懂,摸索出一套指针的用法后,对自己的学习很有用处的。一定要学会自己不断敲打代码,你才会挖掘出有意思的东西。
指针的用途很广泛,这个不能操之过急的想掌握就能掌握的,可以明确的说真理往往是从不断实践中总结出来的。
指针的用法,搞清楚:谁是指针,谁是变量,谁需要地址,谁需要转化为地址。
往往编译器报出无法访问内存,内存溢出,访问冲突等等原因,请记住一定是内存的那里错误,找到源头逐步查看,用编译器的断点功能,你定会有所发现,某个数据要么为NULL,要么是一堆乱码,要么是一堆乱七八糟的数字。。。