开发网站和app,东莞寮步网站建设网络公司,流行的网站设计风格,php家具网站模版动态内存分配
回想C语言中#xff0c;动态内存是怎么分配的#xff1f;通过C库里面的malloc free去进行动态内存分配。 C通过new关键字进行动态内存申请#xff0c;动态内存申请是基于类型进行的。 delete 关键字用于内存释放。
//变量申请
type* pointer new type;
dele…动态内存分配
回想C语言中动态内存是怎么分配的通过C库里面的malloc free去进行动态内存分配。 C通过new关键字进行动态内存申请动态内存申请是基于类型进行的。 delete 关键字用于内存释放。
//变量申请
type* pointer new type;
delete pointer;//数组申请
type* pointer new tyep[10];
delete[] pointer;
//数组释放一定要加 []
int *p new int[10];
//.......
delete p;//会造成内存泄漏。这句话的意思是告诉编译器只释放p指向的一个int型空间而不是所有的数组空间。
delete [] p;//正确的写法new关键字与malloc函数的区别
new关键字是c的一部分malloc是由c库提供的函数。new以具体类型为单位进行内存分配而malloc只能以字节为单位进行内存分配。new在申请单个类型变量时可进行初始化malloc不具备内存初始化的特性。
#include stdio.hint main()
{int* a new int(6);float* b new float(7.0);char* c new char(c);printf(*a %d, *b %f, *c %c\n, *a, *b, *c);delete a;delete b;delete c;return 0;
}C中命名空间
在C语言中只有一个全局作用域。C语言中所有的全局标识符共享同一个作用域那么项目很大时标识符之间就有可能发生冲突。 C中提出了命名空间的概念。目的是将全局作用域划分为不同的块。 命名空间定义 namespace name { /…/}
#include stdio.h
namespace First
{int i 0;
}
namespace Second
{int i 1;namespace Internal{struct P{int x;int y;};}
}int main()
{return 0;
}命名空间的使用
使用整个命名空间 using namespace name; 使用命名空间中的变量using name::variable 使用默认命名空间中的变量::variable 默认情况下可以直接使用默认命名空间中所有的标识符。
#include stdio.h
namespace First
{int i 0;
}
namespace Second
{int i 1;namespace Internal{struct P{int x;int y;};}
}int main()
{using namespace First;//告诉编译器解开First域using Second::Internal::P;//告诉编译器要用Second空间中Internal空间中的P成员变量。printf(i %d\n, i);//打印0使用的是First 空间中的i。因为我们没有解开Second 空间printf(i %d\n, Second::i);//打印1告诉编译器访问的是Second 空间中的i。P p {2, 3};printf(p.x%d, p.y%d\n, p.x, p.y);return 0;
}强制类型转换
C方式的强制类型转换(type)(expression) or type(expression)
#include stdio.h
//定义一个函数指针
typedef void(PF)(int);struct Point
{int x;int y;
};int main()
{int v 0x12345;//将变量v强制类型转换为函数指针PF* pf (PF*)v;//将变量v强制类型转换为char型char c char(v);//调用v变量强制转换为函数的地址函数此处不一定是函数。pf(v);//将v变量强制转换为结构体指针。Point* p (Point*) v;printf(p-x %d\n, p-x);printf(p-y %d\n, p-y);
}C强制类型转换过于粗暴任意类型之间都可以进行转换编译器很难判断其正确性且在源码中无法快速定位所有使用强制类型转换的语句出现问题时难以定位。 在现代软件工程中最难定位问题的三种问题 1.强制类型转换。 2.多线程的交互。 3.位运算优先级数学运算、逻辑运算混在一起。 在程序设计理论中强制类型转换也是不被推荐的与goto语句一样尽量避免。 C提供了更安全的强制类型转换。将强制类型转换分为4中不同的类型。static_cast const_cast dynamic_cast reinterpret_cast 。用法xxx_casttype(expression)
static_cast
用于基本类型间的转换但不能用于基本类型指针间的转换用于有继承关系类对象之间的转换和类指针之间的转换。
#include stdio.hint main()
{int i 8;char c B;int* pi i;char * pc c;c static_castchar(i);pc static_castchar*(pi); return 0;
}static_cast是编译期进行转换的无法在运行时检测类型。所以类类型之间的转换可能存在风险。
const_cast
用于去除变量的const属性
#include stdio.hint main()
{//const 引用j,初始化的时候j就是一个只读变量。//注意第二节讲到 const引用只有定义的别名拥有只读属性不会影响到正名const int j 1;//将只读变量j的const属性去掉j就降级为普通变量。int k const_castint(j);//声明一个真正的常量x。const int x 2;//由于对x常量取引用前面学习了引用本身就是地址别名是指针。//所以此处编译器会为这个常量分配一个空间。//y就指向了常量x的地址y就变成了普通变量。int y const_castint(x);//将j的值改为6k 6;//j 和 k的值一致。printf(j %d,k %d\n, j, k);//将x的变量改成8y 8;//所以x 和 y的地址一样的。//const引用只有定义的别名拥有只读属性不会影响到正名所以x的值还是2因为是常量编译器直接替换。printf(x %d, y %d\n, x, y);printf(x %p, y %p\n, x, y);return 0;
}上面程序中运用到了第二节的知识点const 常量只有定义的别名拥有只读属性不会影响到正名。 int y const_castint(x);在解除const属性时会为x分配内存空间此时引用y指向这段编译器为x分配的空间引用y就是普通变量。但是x还是常量编译器依然认为其不能被赋值。假如下面有一段语句x8则编译器还是会报错。
reinterpret_cast
用于指针类型间的强制类型转换用于整数和指针类型间的强制转换 reinterpret_cast直接从二进制位进行复制是一种及其不安全的转换。
#include stdio.htypedef void (PF)(int);int main()
{int i 0;char c C;//将字符变量c的地址强制转换为int型指针并且赋值给pi指针。int* pi reinterpret_castint*(c);//将int变量i的地址强制转换为char型指针并赋值给pc指针。char* pc reinterpret_castchar*(i);//将0x888888地址强制转换为PF型函数指针并赋值给pf指针。PF* pf reinterpret_castPF*(0x888888);//将int类型变量转换为char不是用reinterpret_cast而是static_castc reinterpret_castchar(i);return 0;
}dynamic_cast
主要用于类层次间的转换还可以用于类之间的交叉转换具有运行时类型检查的功能比static_cast更安全
类是什么对象是什么类层次是什么
小结
C中内置了动态内存分配的专用关键字C中的动态内存分配是基于类型进行的C的malloc函数是基于字节为单位分配。C中命名空间的概念用于解决符号名相同的冲突问题。C细化了C语言中强制类型转换方式。C不推荐在程序中使用强制类型转换建议在强制类型转换时考虑一下究竟希望什么样的转换。