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

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扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版