你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

c++——内存分配、命名空间、强制类型转换

[复制链接]
gaosmile 发布时间:2020-8-2 23:33
一、C++动态内存分配:
在学习c语言的时候,我们一般都是使用库函数malloc()来进行内存的申请分配,然后使用库函数free()来进行释放申请到的内存;现在在c++里面采用了另外一种内存申请的方法:
  • c++中通过new关键字进行动态内存申请。
  • C++中的动态内存申请是基于类型进行的。
  • delete关键字用于内存释放。

下面是申请内存的类型:
变量申请格式:


Type* pointer = new Type;

//

delete pointer



数组申请格式:


Type *pointer = new Type[N];

//

delete [] pointer;
  

下面我们来看一个例子:
#include <stdio.h>

int main()
{
    int *p = new int;
    *p=5;
    *p=*p+10;

    printf("p= %p\n",p);
    printf("*p=%d\n",*p);

    delete p;

    p = new int[10];

    for(int i=0;i<10;i++)
    {
       p=i+1;
       printf("p[%d] = %d\n",i,p);
    }

    delete [] p;

    return 0;

}

输出结果:
p= 0xb6d010
*p=15
p[0] = 1
p[1] = 2
p[2] = 3
p[3] = 4
p[4] = 5
p[5] = 6
p[6] = 7
p[7] = 8
p[8] = 9
p[9] = 10

二、new关键字与malloc函数的区别:
1、new关键字是C++的一部分。

2、malloc是由c库函数提供的。

3、new关键字以具体类型为单位进行内存分配。

4、malloc函数是以字节为单位进行内存分配。

5、new关键在申请单个类型变量时可以进行初始化。

6、malloc 不可以进行内存初始化。

我们来看使用new关键字是如何进行初始化的:
#include <stdio.h>
int main()
{
    int * pi = new int(1);
    float *pf = new float(2.0f);
    char *pc = new char('c');

    printf("*pi=%d\n",*pi);
    printf("*pf=%f\n",*pf);
    printf("*pc=%c\n",*pc);

    delete pi;
    delete pf;
    delete pc;

   return 0;


}

输出结果:
*pi=1
*pf=2.000000
*pc=c

三、c++ 中的命名空间:
在c语言中只有一个全局作用域:
  • c语言中所有的全局标识符共享同一个作用域。
  • 标识符之间可能会发生冲突。-

c++中提出了命名空间的概念:
  • 命名空间将全局作用域分成不同的部分。
  • 不同命名空间中的标识符可以同名而且不会发生冲突。
  • 命名空间可以相互嵌套。
  • 全局作用域也叫默认命名空间。

1、下面我们来看一下c++中命名空间的定义:
namespace Name
{
     namespace Internal
     {
     
     
     
     }
}

2、c++命名空间的使用:
  • 使用整个命名空间:using namespace name;
  • 使用命名空间中的变量:using name::variable;
  • 使用默认命名空间中的变量:::variable;

3、代码示例:
#include <stdio.h>

namespace First
{
     int i =0;

}

namespace Second
{

   int i =1;
   namespace Internal
  {

     struct Test
     {
         int x;
         int y;

     };

  }

}
int main()
{
   using namespace First;
   using Second::Internal::Test;

   printf("First::i is %d\n",i);
   printf("Second::i is %d\n",Second::i);

  Test i={2,4};

  printf("i.x is %d\n",i.x);
  printf("i.y is %d\n",i.y);

  return 0;



}

输出结果:
First::i is 0
Second::i is 1
i.x is 2
i.y is 4

四、c++中的四种强制类型转换

强制类型转换类型汇总

static_castconst_cast
dynamic_castreinterpret_cast
用法:xxx_cast(Expression)
下面是每种强制类型的具体讲解:
1、static_cast强制类型转换:
  • 用于基本类型之间的转换
  • 不能用于基本类型指针之间的转换
  • 用于有继承关系类对象之间的转换和类指针之间的的转换

代码解析:
#include <stdio.h>

void static_cast_demo()
{
    int i =55;
    char c ='c';
    int *pi =&i;
    char *pc =&pc;

    c=static_cast<char>(i);
    pc=static_cast<char*>(pi);

}
int main()
{
    static_cast_demo();

    return 0;

}

输出结果:
t.cpp: In function ‘void static_cast_demo()’:
t.cpp:8:16: error: cannot convert ‘char**’ to ‘char*’ in initialization
     char *pc =&pc;
                ^
t.cpp:11:29: error: invalid static_cast from type ‘int*’ to type ‘char*’
     pc=static_cast<char*>(pi);
                             ^

刚好验证了我们上面说的static_cast不能用在基本类型指针之间进行强制转换。
2、const_cast强制类型转换:
  • 用于去除变量的只读属性
  • 强制类型转换的目标类型必须是指针或者引用

代码解析:
#include <stdio.h>

void const_cast_demo()
{
    const int& j =2;
    int& k = const_cast<int&>(j);

    const int x = 4;
    int& y = const_cast<int&>(x);

    int z = const_cast<int>(x);

    k=8;

   printf("k=%d\n",k);
   printf("j=%d\n",j);

   j =12;

   printf("x=%d\n",x);
   printf("y=%d\n",y);
   printf("&x=%p\n",&x);
}
int main()
{
    const_cast_demo();

    return 0;

}

输出结果:
t.cpp: In function ‘void const_cast_demo()’:
t.cpp:11:30: error: invalid use of const_cast with type ‘int’, which is not a pointer, reference, nor a pointer-to-data-member type
     int z = const_cast<int>(x);
                              ^
t.cpp:18:6: error: assignment of read-only reference ‘j’
    j =12;

通过上面的z转换,我们可以发现它的目标不是指针或者引用,所以报错。
3、reinterpret_cast强制类型转换:
  • 用于指针类型之间的强制转换
  • 用于整数和指针类型之间的强制转换

代码解析:
#include <stdio.h>
void reinterpret_cast_demo()
{
    int i =2;
    char c = 'c';
    int *pi = &i;
    char *pc =&c;

    pc=reinterpret_cast<char*>(pi);
    pi=reinterpret_cast<int*>(pc);
    pi=reinterpret_cast<int*>(i);
    c=reinterpret_cast<char(i);


}

int main()
{
    reinterpret_cast_demo();

    return 0;

}

输出结果:
t.cpp: In function ‘void reinterpret_cast_demo()’:
t.cpp:12:28: error: expected ‘>’ before ‘(’ token
     c=reinterpret_cast<char(i);
                            ^
t.cpp:12:30: error: invalid cast from type ‘int’ to type ‘char’
     c=reinterpret_cast<char(i);

从结果我们可以看到,它用于整数之间的转换,不符合规则,所以报错。
4、dynamic_cast强制类型转换(暂时有些概念没有学到,先记住结论):
  • 用于有继承关系的类指针之间的转换
  • 用于有交叉关系的类指针之间的转换
  • 具有类型检查的功能
  • 需要虚函数的支持

代码分析:
#include <stdio.h>
void dynamic_cast_demo()
{
      int i =2;
      int *pi=&i;
      char *pc =dynamic_cast<char*>(pi);

}

int main()
{
    dynamic_cast_demo();

    return 0;

}

输出结果:
.cpp: In function ‘void dynamic_cast_demo()’:
t.cpp:6:39: error: cannot dynamic_cast ‘pi’ (of type ‘int*’) to type ‘char*’ (target is not pointer or reference to class)
       char *pc =dynamic_cast<char*>(pi);

不符合规则,所以报错。
5、小结:
上面四种类型转换的例子,前三种把错误的地方给屏蔽掉,就是正确的例子,第四种类型转换,暂时继承的概念没有学到,所以这个例子不是很好。
同时内存分配的使用,本次也只是简单的说了一下概念,在真正实操当中,还是有很多要注意的地方,下期文章我们再详细解析。

收藏 评论1 发布时间:2020-8-2 23:33

举报

1个回答
likang1202 回答时间:2020-8-3 09:37:10
顶一下
mark.png

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版