一、范围for语句
for语句用于遍历一个序列的例子
#include#include using namespace std; int main() { int data[]={ 1,2,3,4,5,6,7,8,9,10 }; //方式一:data数组的元素拷贝 for(auto i:data) //数组data中的每一个元素依次拷贝到i中,并打印i值 { cout << i<<" "; } cout << endl; //方式二:省了拷贝动作,提高了程序执行效率,推荐这样使用 for (auto &i : data) //直接把用i引用data数组元素,类似于i指针指向data数组中的元素地址 { cout << i << " "; } cout << endl; return 0; }
方式一:程序执行和内存信息
方式二:序执行和内存信息
二、动态内存分配问题
C/C++中,我们把内存详细分为5个区域:
1、栈:一般函数内的局部变量、形参存在栈中,由编译器自动分配和释放,内存分配效率高,空间有限;
2、堆:程序员手动malloc/new分配,用free/delete来释放;如果程序员忘记释放后,内存一直被占用,直到程序结束后,系统会自动回收。
3、全局/静态存储区:放全局变量和静态变量static,程序结束时系统释放;
4、常量存储区:如”HelloWorld!”存在常量区,const修饰的变量也存储在常量区,const修饰的局部变量依然存在栈中。
5、程序代码区。存放源程序的二进制代码。
堆和栈的用途和区别
栈:系统规定的空间。如int data=16;系统自动分配4字节的空间给data。
如果一个函数中用递归或者while(1)死循环执行很大的程序,会出现栈空间不够溢出的现象。
栈分配速度快。
堆:只有不超出时间拥有的物理内存,也在操作系统允许你能够分配的最大内存大小之内,都可以分配给你。
堆分配速度比栈慢。
堆空间的分配有:
A、C语言的是由mallocrealloccalloc分配内存,free释放内存。
B、C++语言是由new分配内存,free释放内存。
下面对C语言内存开辟和释放用到的函数进行讲解:
malloc函数
使用时 必须包含头文件
函数原型: void * malloc (size_ t size) ;
功能:
(1)开辟一块size大小的连续堆内存。
(2)size表示堆上所开辟内存的大小(字节数)。
(3)函数返回值是一个指针,指向刚刚开辟的内存的首地址。
(4)如果开辟内存失败, 返回一个空指针,即返回值为NULL。
(5)当内存不再使用时,应使用free ()函数将内存块释放
realloc函数
函数原型:
使用时必须包含头文件
void * realloc(void * mem_ address, size_ t newsize) ;
功能:
(1)为已有内存的变量重新分配新的内存大小(可大、可小) ;
(2)先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_ address返回,要开辟新的内存大小一定要大于原来的内存大小,否则会造成数据丢失。
(3)如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address 所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
(4)如果重新分配成功则返回指向被分配内存的指针;
(5)如果分配不成功,返回NULL,原来的内存不改变,不会释放也不会移动。
(6)当内存不再使用时,应使用free ()函数将内存块释放。
calloc函数
使用时 必须包含头文件
函数原型: void * calloc(size_ t n, size t size);
功能:
(1)在内存的动态存储区中分配n个长度为si ze的连续空间;
(2)函数返回一个指向分配起始地址的指针;
(3)如果分配不成功,返回NULL。
(4)当内存不再使用时,应使用free ()函数将内存块释放。
(5)calloc申请内存成功后,会把原来的脏内存都清零,内存申请执行效率没有malloc高。
free函数
使用时 必须包含头文件
函数原型: void free (void *ptr) ; //ptr为要释放的内存指针。
free():释放指针变量在堆区上的内存空间,不能释放栈上的内存空间,free要与malloc(calloc、realloc)成对使用。
C++语言的是new分配内存和delete释放内存
new一般使用形式:
(1)指针变量名 = new 类型标识符。例子如下:
#include#include using namespace std; int main() { int* myInt = new int; if (myInt != NULL) { *myInt = 10; cout << *myInt << endl; delete myInt; } }
控制台输出如下:
(2)指针类型名 = new 类型标识符(初始值)//注意这里是圆括号括起来,表示初始值。例子如下:
#include#include using namespace std; int main() { int* myInt = new int(18); if (myInt != NULL) { cout << *myInt << endl; delete myInt; } }
控制台输出如下:
3、指针类型名 = new 类型标识符[内存单元个数] //注意,这里是[ ],分配一个数组。例子如下:
int *p=new int[100];//开辟一个大小为100的整型数组空间
if(p != NULL)
{
int* q = p;
*q++ = 12; //[0]=12
*q++ = 18;//[1]=18,执行完这一行,这个q其实已经指向[2]
cout << *p << endl;
cout << *(p + 1) << endl;
delete[]p; //特别注意:释放int p数组空间,初始化时用[],则释放内存也需要带[],释放内存时[]不需要写释放内存大小
特别注意:
(1)malloc、realloc和calloc必须与free成对使用;
(2)如果只用malloc(calloc、realloc)开辟空间,没有用free 释放内存, 会造成内存泄漏;
(3)如果用malloc(calloc、realloc) 开辟了空间,而后已经用 free把开辟的内存空间释放了,再单独用free会造成二次删除, 破坏内存,导致程序崩溃。
(4)C语言用malloc、realloc和calloc必须与free,C++用 new和delete。
三、指针空类型nullptr
nullptr是C++11中引用的新关键字,表示一个空指针。
char *p=NULL;
char *q=nullptr;
int *ptr=nullptr;
int m= NULL; //不会报错
//int n=nullptr; //报错
if(p==nullptr)
{
cout<<”p==nullptr”<
到这里还是没有办法区分NULL和nullptr的区别,下面我们打印出它俩的类型看看现象:
cout << endl;
cout << "NULL data type is"<
控制台打印信息如下:
结论:在C++语言中,在初始化指针时,用nllptr取代NULL。



