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> // 传递指针给函数& ...
随机推荐
- SQLSERVER中分割字符串成多列
今天修改到之前的大佬的代码,居然把多个Id存在一个列里面,还是用的逗号分割...特么查询的时候怎么办??? 网上搜索了半天,终于找到了SqlServer里面有一个PARSENAME函数,可以按.(点) ...
- Jupyter 初体验
简介 Jupyter notebook 是一个非常强大的工具,可以创建漂亮的交互式文档. 安装 安装环境:win7专业版32位系统 + python 3.6.4 安装命令:pip install ju ...
- HZAU 1199: Little Red Riding Hood 01背包
题目链接:1199: Little Red Riding Hood 思路:dp(i)表示前i朵花能取得的最大价值,每一朵花有两种选择,摘与不摘,摘了第i朵花后第i-k到i+k的花全部枯萎,那么摘的话d ...
- 关于使用srping @RequestParam 容易出错的地方
大家都知道,在spring中的@RequestParam主要用户传递参数用的,具体的解释就是将请求参数去数据映射到功能处理方法的参数上.其中包括三个参数: value:参数名字,即入参的请求参数名字, ...
- HashPayloadPcapReader
package net.ripe.hadoop.pcap; import java.io.DataInputStream; import java.io.IOException; import com ...
- php 变量原理讲解
php 变量原理讲解 一.变量概念 所谓变量,是指在程序中其值可以变化的量. 程序是管理和处理数据的.在程序运行过程中,我们需要存贮这些数据,变量和常量就是用于保存程序运行时的数据的. 变量通常由 ...
- dojo省份地市级联之省份Dao实现类(五)
dojo省份地市级联之省份Dao实现类 ProvinceDaoImpl.java: /** * */ package com.you.dao.impl; import java.util.ArrayL ...
- Caused by: java.lang.NoClassDefFoundError: org/springframework/web/context/WebApplicationContext
1.错误描述 严重: A child container failed during start java.util.concurrent.ExecutionException: org.apache ...
- solaris启动过程详解
在Sparc平台下,Solaris系统中有一个类似PC BIOS的芯片程序(EEPROM OpenBoot)负责识别分区.文 件系统和加载内核,在Solaris 2.6之后的版本中,默认的内核文件存放 ...
- 修改MyEclipse编辑框背景色
修改MyEclipse编辑框背景色 1.未修改之前,编辑框背景色 2.依次操作,"Window--->Preferences" 3.选择"General---> ...