现在讲一下指针的主要用途和常见错误。


[用途]

1.用作形参

  首先,常见新手写交换函数:

 void swap(int a,int b){
int t = a;
a = b;
b = t;
}

  主函数里调用一下试试,看看a,b的值有没有改变?

 #include<iostream>
#include<stdlib.h>
using namespace std;
void swap(int,int);
int main(){
int a = ;
int b = ;
swap(a,b);
cout<<a<<" "<<b;
return ;
}
void swap(int a,int b){
int t = a;
a = b;
b = t;
}

  运行结果就不公布了,对于新手,有木有发现什么不对的地方?

是什么原因造成这个结果的呢?应该是内存地址吧,要同一内存地址修改其中一个的值

才会改变另一个的值,那来验证一下:

#include<iostream>
#include<stdlib.h>
using namespace std;
void swap(int,int);
int main(){
int a = ;
int b = ;
cout<<"address in main: &a = "<<&a<<" &b = "<<&b<<endl;
swap(a,b);
cout<<a<<" "<<b;
return ;
}
void swap(int a,int b){
int t = a;
a = b;
b = t;
cout<<"address in swap: &a = "<<&a<<" &b = "<<&b<<endl;
}

运行结果

address in main: &a = 0x22fedc &b = 0x22fed8
address in swap: &a = 0x22fec0 &b = 0x22fec4

看来确实是这样的。。。

那么要是swap和main函数中a,b两变量的内存地址相等,可以用指针来完成

 #include<iostream>
#include<stdlib.h>
using namespace std;
void swap(int*,int*);
int main(){
int a = ;
int b = ;
cout<<"address in main: &a = "<<&a<<" &b = "<<&b<<endl;
swap(&a,&b);
cout<<a<<" "<<b;
return ;
}
void swap(int* a,int* b){
int t = *a;
*a = *b;
*b = t;
cout<<"address in swap: &a = "<<a<<" &b = "<<b<<endl;
}

运行结果

address in main: &a = 0x22fedc &b = 0x22fed8
address in swap: &a = 0x22fedc &b = 0x22fed8

(注:如果读者知道,其实还有一种代码写起来可读性比指针高,错误率比指针低的方式,就是用引用&)

2.提高运行速度

  随便打了篇代码来做实验,第一个seta函数是不用指针给结构体中的数据赋值,第二个setb函数时用指针给

结构体中的数据赋值

 

 #include<iostream>
#include<ctime>
using namespace std;
struct a{
int a[];
int len;
}c;
a seta(a b,int index,int val){
b.a[index] = val;
return b;
}
a setb(a *b,int index, int val){
b->a[index] = val;
return *b;
}
int main(){
clock_t begin = clock();
for(int i = ;i < ;i++)
c = seta(c, i, i);
clock_t end = clock(); clock_t begin1 = clock();
for(int i = ;i < ;i++)
c = setb(&c, i, i);
clock_t end1 = clock(); cout<<"非指针:"<<(end - begin)<<"ms"<<endl;
cout<<"指针 :"<<(end1 - begin1)<<"ms"<<endl;
return ;
}

运行结果(鉴于我家渣机外加开了很多程序所以运行地很慢):

非指针:1781ms
指针 :672ms

有木有发现什么明显的差距,稍微微调一下,把setb函数改成:

void setb(a *b,int index, int val){
b->a[index] = val;
}

然后编译运行,神奇的事发生了:

非指针:1078ms
指针 :0ms

是不是很神奇?

想知道这是为什么吗?

  因为在结构体传递的时候是值传递,又因为数组很大,所以要拷贝过来,赋值的

时候也是需要拷贝,所以非常消耗时间,而指针是地址传递,相当于是一个要复制

一个数组,而另一个却只用复制4字节的数据就完成了一样的事

  其实还可以比较一下,指针和引用的时间消耗:

 #include<iostream>
#include<ctime>
using namespace std;
struct a{
int a[];
int len;
}c;
void seta(a& b,int index,int val){
b.a[index] = val;
}
void setb(a *b,int index, int val){
b->a[index] = val;
}
int main(){
clock_t begin = clock();
for(int i = ;i < ;i++)
seta(c, i, i);
clock_t end = clock(); clock_t begin1 = clock();
for(int i = ;i < ;i++)
setb(&c, i, i);
clock_t end1 = clock(); cout<<"引用:"<<(end - begin)<<"ms"<<endl;
cout<<"指针:"<<(end1 - begin1)<<"ms"<<endl;
return ;
}

  结果可以多运行几次,不行可以加大数据,指针和引用貌似时间消耗差不多,不过引用写起来是要

比指针简单一些,像这样也就最多有10ms

3.用于各种数据结构

  例如各种树结构,链表等

4.给指定内存存储的数据赋值(在开发操作系统时,这貌似是允许的)

5.通过new、malloc等来省内存


[常见错误]

1.空内存地址

  当一个指针的值等于 0x00(NULL,windef.h下定义)时,这必定是一个空内存,如果用到了访问*,程序直接崩溃,访问无效内存

还有就是与其它程序或者系统的专用内存段等冲突,也会导致程序崩溃,这就是因为即使有时候数组下标超了一点点时也可能不会崩溃

的原因

2.访问用过delete或free()后的指针

3.滥用指针,导致浪费内存

另外指针经常也很难看懂,比如,你能一样告诉我这是什么类型的指针吗?(下)

typedef char*const(*p)(long long);

总之指针还得多使用,能用熟最好,不然最好不用,用引用去代替它,

如果到什么开发什么程序的时候,程序崩溃了,都不知道为什么,那

可就糟了

[c/c++]指针(4)的更多相关文章

  1. TODO:Golang指针使用注意事项

    TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...

  2. enote笔记法使用范例(2)——指针(1)智能指针

    要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...

  3. C++虚函数和函数指针一起使用

    C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...

  4. C++11 shared_ptr 智能指针 的使用,避免内存泄露

    多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...

  5. c 数组与指针的使用注意事项

    数组变量和指针变量有一点小小的区别 所以把数组指针赋值给指针变量的时候千万要小心 加入把数组赋值给指针变量,指针变量只会包含数组的地址信息 而对数组的长度一无所知 相当于指针丢失了一部分信息,我们把这 ...

  6. Marshal.Copy将指针拷贝给数组

    lpStatuss是一个UNITSTATUS*的指针类型实例,并包含SensorDust字段 //定义一个数组类型 byte[] SensorDust = new byte[30] //将指针类型拷贝 ...

  7. C++智能指针

    引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...

  8. EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针

    一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...

  9. 智能指针shared_ptr的用法

    为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...

  10. 智能指针unique_ptr的用法

    unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...

随机推荐

  1. The History of Operating Systems

    COMPPUTER SCIENCE AN OVERVIEW 11th Edition job 作业 batch processing 批处理 queue 队列 job queue 作业队列 first ...

  2. android call and audio

    mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system ConnCtl *:s android audio (http://blog.cs ...

  3. 关于LeNet-5卷积神经网络 S2层与C3层连接的参数计算的思考???

    https://blog.csdn.net/saw009/article/details/80590245 关于LeNet-5卷积神经网络 S2层与C3层连接的参数计算的思考??? 首先图1是LeNe ...

  4. linux rz sz的安装

    可以使用yum来安装 yum -y install lrzsz 然后rz就是上传文件,sz就是把文件导到本地.sz 文件名  即可

  5. ovs的主要代码函数及大体结构图

    作者: 北京-小武 邮箱:night_elf1020@163.com 新浪微博:北京-小武 最终抽时间把openvswitch的2.0代码看的思路汇总了下,因为是曾经好早下载的.看完了也才看到2.1依 ...

  6. Python3学习之路~2.5 简单的三级菜单程序

    程序:三级菜单 需求: 1.打印省.市.县三级菜单2.可返回上一级3.可随时退出程序 代码1: data={ "山东":{ "济南":["历下区&qu ...

  7. 使用vue如何默认选中单选框

    使用了vue以后,发现这真的是一个灵活高效的框架,能够轻松实现页面的实时刷新.那么,今天先聊聊单选框的使用.一般我们使用单选框,会这么写: //HTML <input type=" c ...

  8. mac shell终端编辑命令行快捷键

    Ctrl + d        删除一个字符,相当于通常的Delete键(命令行若无所有字符,则相当于exit:处理多行标准输入时也表示eof) Ctrl + h        退格删除一个字符,相当 ...

  9. kmeans聚类源代码

    代码是在weka上二次开发的,但没有使用原来的kmeans代码,只是用了它的数据类Intances,先说下与它相关的几点东西. 一.KMeans算法简介 输入:聚类个数k,以及包含 n个数据对象的数据 ...

  10. numpy排序(sort、argsort、lexsort、partition、sorted)

    1.sort numpy.sort(a, axis=1, kind='quicksort', order=None) a :所需排序的数组 axis:数组排序时的基准,axis=0按行排列:axis= ...