c++ 指针总结 函数参数指针调用和堆栈内存的分配原理
c++中的char指针
这个char指针很有意思,char指针通常有两种初始化形式.一个是使用char数组初始化,一个是使用char变量初始化.
c++当中使用双引号括起来的字符串起始已经被编译器初始化为一个const char[]类型的字符串常量.也就是说"hedd"在赋值给其他变量或常量时实际上是将一个已经在内存中分配了地址的const char数组的头指针赋值给它.如果你使用's'这样的数字量是不能直接赋值给char指针的,因为's'是一个字符而不是拥有内存的字符变量或常量.这种情况必须使用char变量或者const char在内存中申请内存并初始化为一个字符,然后使用这个变量或常量赋值给cha指针.
使用cout或printf输出char指针指向的数据
在使用cout或printf输出char指针时,他们的策略是如果是char指针,则会从指针指向的第一个内存区域开始读数据,一直向后读取数据直至获得了'\0'结尾字符.
所以听过cout输出char指针指向的地址是不现实的,必须将char指针抢转为其他指针,一般我会使用转化为void指针.这样转化之后机会输出char指针指向的内存块地址了.
cout和printf只有对字符指针有这样的独特判断,对于其他类型的指针将直接输出指针所在的地址,而不会去读该地址的内容,更不会一直读取下一个地址的内容直至遇到'\0'结尾字符.

从上图我们就可以发现,cout对char指针使用*取值还是正常的,他只会去所指向的地址内存有的数据.而不会自动读取下一个地址的内容

从上图我们可以发现,当使用一个char变量地址给char指针,然后使用cout输出时,cout会自动读取char变量后面地址的内容,直至发现一个内容转化char等于'\0'字符的地址.使用这种方式就存在着越界读取的情况.

现在我们回头想象就明白为什么使用cout读取char i[6]={'h','e','l','l','\0'}和"hello" 以及const char*p="hello"的结果是一样的了.同时我们也发现,编译器是允许我们使用"hello"对const char j[6]数组直接赋值的.
这时我们就可以考虑一个事情了,我们是否可以运用这个特性对其他字符进行这样的赋值而不需要使用数组的单个赋值呢?

从上图我们发现我们是可以将int型地址转为char 然后通过他赋值char数组的,但是对于其他数组形式我们这里就没有测试了.
堆和栈内存
我们都知道程序都是有自己的堆和栈内存的,我们使用的变量,常量一般都是放在栈当中,常量和全局变量一般放在全局栈中,而函数的局部变量都放置在函数的局部栈当中.当我们不适用堆内存而只是用栈内存处理函数调用间的数据时,要防止破坏函数的调用栈,如果破坏掉程序将报异常,有时候的异常还是很难定位的.

void func(char * msg_)
当func被调用时,他的参数是一个指针,这个指针指向的是这个函数之外的地址,虽然这个指针是局部作用域中的,因此很有必要在使用时将这个指针指向的内容复制到一个局部变量中.在多线程时很可能会因为外部指针的实效而出现指向无用指针的情况.如果不使用这种方式的另一种方式就是使用堆,因为堆的内存不会被自动释放掉.->因此在多线程等环境中,参数为指针的,虽然讲数据的指针传过来,但是并不代表着这个指针一致有效,应该在传入时将指针所指向的数据备份在局部变量中.
void func2(char & msg_)
这个传进来的是一个char变量,严格上将是传递一个指针,只是msg_变量是实参的引用.他指向的了char类型的变量.因为参数里的类型是char而不是char* ,虽然进来的是同样的地址但是参数规定了他是一个char变量而不是一个char数组.所以还是需要使用char* 来传递字符串.
c++ 指针总结 函数参数指针调用和堆栈内存的分配原理的更多相关文章
- C++ 有关指针作为函数参数的问题,自定义内存分配函数传递二级指针的问题
如题所示,我们主要讨论在自定义的内存分配函数中通常见到的代码如下所示: void Create(A** addr); 其中传递的参数是二级指针.为什么? 我们先看一下完整的动态内存分配函数的简单例子: ...
- C++ 二维数组(双重指针作为函数参数)
本文的学习内容参考:http://blog.csdn.net/yunyun1886358/article/details/5659851 http://blog.csdn.net/xudongdong ...
- Day8 函数指针做函数参数
课堂笔记 课程回顾 多态 virtual关键字 纯虚函数 virtual func() = 0; 提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. ...
- go语言基础之数组指针做函数参数
1.数组指针做函数参数 示例: package main //必须有个main包 import "fmt" //p指向实现数组a,它是指向数组,它是数组指针 //*p代表指针所指向 ...
- go语言基础之指针做函数参数用地址传递
1.指针做函数参数 示例: package main //必须有个main包 import "fmt" func swap(p1, p2 *int) { *p1, *p2 = *p ...
- go语言基础之指针做函数参数
1.指针做函数参数 示例: package main //必须有个main包 import "fmt" func swap(a, b int) { a, b = b, a fmt. ...
- [编程] C语言结构体指针作为函数参数
结构体指针作为函数参数:结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针.如果结构体成员较多,尤其是成员为数组时,传送的时间和空间 ...
- 【转载】C/C++杂记:深入理解数据成员指针、函数成员指针
原文:C/C++杂记:深入理解数据成员指针.函数成员指针 1. 数据成员指针 对于普通指针变量来说,其值是它所指向的地址,0表示空指针.而对于数据成员指针变量来说,其值是数据成员所在地址相对于对象起始 ...
- C基础知识(5):指针--传递指针给函数&返回指针的函数
下面从3个代码例子分别讲述以下2个知识点: (1) 传递指针给函数(参数类型为指针) (2) 返回指针的函数(返回类型为指针) #include <stdio.h> // 传递指针给函数& ...
随机推荐
- Python 判断闰年,判断日期是当前年的第几天
http://www.cnblogs.com/vamei/archive/2012/07/19/2600135.html Python小题目 针对快速教程 作业答案 写一个程序,判断2008年是否是闰 ...
- Java long类型和Long类型的那些事
还记得最近做了一个项目使用的是Long类型作为主键Id坑死人了,对于我们来说Long类型一样是一个包装类型,类似String类型,使用==符号进行比较的时候有时候会出现问题,建议适应equal()方法 ...
- Mysql给某一台主机授权访问,修改root密码
ubuntu上用的是phpstudy,安装好之后,敲mysql,提示没有,需要安装mysql的客户端. 安装好之后直接敲mysql,敲 mysql 再敲use mysql 再敲mysql -uroot ...
- 隐藏文件的查看(Win/Linux/macOS)
Windows(10): 点查看->点选项,弹出文件夹选项,点查看,高级设置里找到隐藏文件和文件夹这个选项,按需求选显示或者隐藏即可. Linux: Linux下,类似于.ssh开头的文件或者文 ...
- Redis的两种持久化方式-快照持久化和AOF持久化
Redis为了内部数据的安全考虑,会把本身的数据以文件形式保存到硬盘中一份,在服务器重启之后会自动把硬盘的数据恢复到内存(redis)的里边,数据保存到硬盘的过程就称为"持久化"效 ...
- Google 浏览器被劫持怎么办?
chrome://version/ 输入以上语句,在命令行中可看到恶意网址,复制该命令行,修改后面的网址即可
- AppCompatActivity 去掉标题栏和EditText弹出软键盘遮住输入框问题
1. AppCompatActivity去掉标题栏 此处除掉标题栏,需要注意一点,AppCompactActivity是继承自Activity.然而,AppCompactActivity据查看网上资料 ...
- 【开源】C#.NET股票历史数据采集,【附18年历史数据和源代码】
如果用知乎,可以关注专栏:.NET开源项目和PowerBI社区 重点重点:我没有买股票,没有买股票,股市是个坑,小心割韭菜哦. 本文的初衷是数据分析(分析结果就不说了,就是想看看筛选点数据),只不过搞 ...
- jquery源码分析之一前言篇
1.问:jquery源码分析的版本是什么? 答:v3.2.1 2.问:为什么要分析jquery源码? 答:javascript是一切js框架的基础,jquery.es6.vue.angular.rea ...
- Vue第一个自定义组件:数字输入框(number-input)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...