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++ 指针总结 函数参数指针调用和堆栈内存的分配原理的更多相关文章

  1. C++ 有关指针作为函数参数的问题,自定义内存分配函数传递二级指针的问题

    如题所示,我们主要讨论在自定义的内存分配函数中通常见到的代码如下所示: void Create(A** addr); 其中传递的参数是二级指针.为什么? 我们先看一下完整的动态内存分配函数的简单例子: ...

  2. C++ 二维数组(双重指针作为函数参数)

    本文的学习内容参考:http://blog.csdn.net/yunyun1886358/article/details/5659851 http://blog.csdn.net/xudongdong ...

  3. Day8 函数指针做函数参数

    课堂笔记 课程回顾         多态 virtual关键字 纯虚函数 virtual func() = 0;         提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. ...

  4. go语言基础之数组指针做函数参数

    1.数组指针做函数参数 示例: package main //必须有个main包 import "fmt" //p指向实现数组a,它是指向数组,它是数组指针 //*p代表指针所指向 ...

  5. go语言基础之指针做函数参数用地址传递

    1.指针做函数参数 示例: package main //必须有个main包 import "fmt" func swap(p1, p2 *int) { *p1, *p2 = *p ...

  6. go语言基础之指针做函数参数

    1.指针做函数参数 示例: package main //必须有个main包 import "fmt" func swap(a, b int) { a, b = b, a fmt. ...

  7. [编程] C语言结构体指针作为函数参数

    结构体指针作为函数参数:结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针.如果结构体成员较多,尤其是成员为数组时,传送的时间和空间 ...

  8. 【转载】C/C++杂记:深入理解数据成员指针、函数成员指针

    原文:C/C++杂记:深入理解数据成员指针.函数成员指针 1. 数据成员指针 对于普通指针变量来说,其值是它所指向的地址,0表示空指针.而对于数据成员指针变量来说,其值是数据成员所在地址相对于对象起始 ...

  9. C基础知识(5):指针--传递指针给函数&返回指针的函数

    下面从3个代码例子分别讲述以下2个知识点: (1) 传递指针给函数(参数类型为指针) (2) 返回指针的函数(返回类型为指针) #include <stdio.h> // 传递指针给函数& ...

随机推荐

  1. Sping Boot入门到实战之入门篇(二):第一个Spring Boot应用

    该篇为Spring Boot入门到实战系列入门篇的第二篇.介绍创建Spring Boot应用的几种方法. Spring Boot应用可以通过如下三种方法创建: 通过 https://start.spr ...

  2. python——Django项目模板

    views.py # -*- coding: utf-8 -*- from __future__ import unicode_literals from django.shortcuts impor ...

  3. ubuntu14.04 安装Jenkins

    wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add - sudo sh -c 'ec ...

  4. H3C路由交换常用命令

    1.查看Linux下查看端口状态 root@root:~# netstat -an|grep -E "6002|6003" 2.H3C交换机显示当前配置 [H3C]display ...

  5. S3 Browser 配置指南

    S3 Browser 相对于s3cmd是一个很方便的操作S3的图形化界面工具. 以下是配置步骤: 下载网址:http://s3browser.com/ keygen破解版: http://appdol ...

  6. 定义一个Matrix类,实现矩阵的加法和乘法

    #include<iostream> using namespace std; class Matrix { int row;//矩阵的行 int col;//矩阵的列 int **a;/ ...

  7. ImportError: No module named 'Box2D' 解决办法

    ImportError: No module named 'Box2D'这个问题是由于缺少gym Openai gym是一个用于开发和比较RL算法的工具包,与其他的数值计算库兼容,如tensorflo ...

  8. java 学习第二天小练习

    1.从控制台输入学员王浩3门课程成绩,编写程序实现 ChengJi (1)数学课和英语课的分数之差 (2)3门课的平均分 代码如下: p.p1 { margin: 0.0px 0.0px 0.0px ...

  9. 用SDL库播放yuy2 Packed mode

    #define SDL_YUY2_OVERLAY 0x32595559 /* Packed mode: Y0+U0+Y1+V0 */ if (SDL_Init(SDL_INIT_VIDEO) < ...

  10. linux命令--ldconfig和ldd用法

    一.ldconfig ldconfig是一个动态链接库管理命令,为了让动态链接库为系统所共享,还需运行动态链接库的管理命令--ldconfig. ldconfig 命令的用途,主要是在默认搜寻目录(/ ...