当前位置: 首页 > wzjs >正文

汕头个人网站建设怎么制作网站教程手机

汕头个人网站建设,怎么制作网站教程手机,网站开发名片怎么做,张扬网站建设内存和地址 计算机上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中,那我们买电脑的时候,电脑上内存是 8GB/16GB/32GB 等,那这些内存空间如何⾼效的…

内存和地址

计算机上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中,那我们买电脑的时候,电脑上内存是 8GB/16GB/32GB 等,那这些内存空间如何⾼效的管理

把内存划分为⼀个个的内存单元,每个内存单元的⼤⼩为1个字节
每个内存单元也都有⼀个编号(这个编号就相当于宿舍房间的⻔牌号),有了这个内存单元的编号,CPU就可以快速找到编号对应的内存单元。
⽣活中我们把⻔牌号也叫地址,在计算机中我们把内存单元的编号也称为地址。C语⾔中给地址起了新的名字叫:指针

![[Pasted image 20250314200127.png]]

计算机中常⻅的单位(补充):
⼀个⽐特位可以存储⼀个2进制的位1或者0

bit - ⽐特位  
Byte - 字节  
KB  
MB  
GB  
TB  
PB
1Byte = 8bit  
1KB = 1024Byte  
1MB = 1024KB  
1GB = 1024MB  
1TB = 1024GB  
1PB = 1024TB

指针变量

取地址操作符(&)

C++中创建变量的本质是向内存申请空间

#include <iostream>  
int main()  
{  int a = 10;  return 0;  
}

![[Pasted image 20250314203536.png]]

上述的代码就是创建了整型变量a,在内存中申请4个字节,⽤于存放整数10,申请到的每个
字节都有地址,上图中4个字节的地址分别是

0x0117FAD8  
0x0117FAD9  
0x0117FADA  
0x0117FADB

操作符(&)-取地址操作符

#include <iostream>  
using namespace std;  
int main()  
{  int a = 10;  &a;//取出a的地址  cout << &a << endl;  return 0;  
}

会打印处理: 0117FAD8 &a取出的是a所占4个字节中地址较⼩的字节的地址。
虽然整型变量占⽤4个字节,我们只要知道了第⼀个字节地址,顺藤摸⽠访问到4个字节的数据也是可⾏的。

指针变量

通过取地址操作符(&)拿到的地址是⼀个数值,⽐如: 0x0117FAD8 ,这个数值有时候也是需要存储起来,⽅便后期再使⽤的,那我们把这样的地址值存放在哪⾥呢?答案是:指针变量中

#include <iostream>  
using namespace std;  
int main()  
{  int a = 10;  int * pa = &a;//取出a的地址并存储到指针变量pa中  return 0;  
}

指针变量也是⼀种变量,这种变量就是⽤来存放地址的,存放在指针变量中的值都会理解为地址。
指针变量中存放谁的地址,我们就说这个指针变量指向了谁;上⾯代码中 pa 就是存放 a 的地址,我们就是 pa 指向了 a 变量。
但是有时候⼀个指针变量创建的时候,还不知道存储谁的地址,那怎么办呢?在C++中这时候,我们会给指针变量赋值为 NULL , NULL 的值其实是 0 ,表⽰空指针,意思是没有指向任何有效的变量。
当然 0 也是作为地址编号的,这个地址是⽆法使⽤的,读写该地址会报错

int *p = NULL;

在C++11后,使⽤ nullptr 来代替了 NULL ,我们在代码中也可以直接使⽤ nullptr

如何拆解指针类型
int a = 10;  
int * pa = &a;

这⾥pa左边写的是 int* , * 是在说明pa是指针变量,⽽前⾯的 int 是在说明pa指向的是整型(int) 类型的对象。
![[Pasted image 20250314210605.png]]

那如果有⼀个 char 类型的变量 ch , ch 的地址,要放在什么类型的指针变量中呢?

char ch = 'w';  
pc = &ch; //pc 的类型怎么写呢
解引⽤操作符

C++语⾔中,只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针)指向的对象,这⾥必须学习⼀个操作符叫解引⽤操作符( * )。

#include <iostream>  
using namespace std;  
int main()  
{  int a = 100;  int* pa = &a;  *pa = 0;  cout << a << endl;  return 0;  
}

上⾯代码中第7⾏就使⽤了解引⽤操作符, *pa 的意思就是通过pa中存放的地址,找到指向的空间, *pa 其实就是 a 变量了;所以 *pa = 0 ,这个操作符是把 a 改成了 0 .
这⾥是把a的修改交给了pa来操作,这样对a的修改,就多了⼀种的途径,写代码就会更加灵活
注意:如果⼀个指针变量的值是 NULL 时,表⽰这个指针变量没有指向有效的空间,所以⼀个指针变量的值是 NULL 的时候,是不能解引⽤操作的

指针类型的意义

指针类型的意义体现在两个⽅⾯:

  • 指针的解引⽤
  • 指针±整数
指针的解引⽤
//代码1  
#include <iostream>  
using namespace std;  
int main()  
{  int n = 0x11223344;  int *pi = &n;  *pi = 0;return 0;  
}//代码2  
#include <iostream>  
using namespace std;  
int main()  
{  int n = 0x11223344;  char *pc = (char *)&n;  *pc = 0;  return 0;  
}

调试我们可以看到,代码1会将 n 的 4 个字节全部改为 0 ,但是代码2只是将 n 的第1个字节改为0 。
结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。
⽐如: char* 的指针解引⽤就只能访问⼀个字节,⽽ int* 的指针的解引⽤就能访问四个字节。
![[Pasted image 20250314210947.png]]

指针±整数
#include <cstdio>  
int main()  
{  int n = 10;  char* pc = (char*)&n;  int * pi = &n;  printf("&n = %p\n", &n);  printf("pc = %p\n", pc); //字符的地址使⽤cout打印会以为是字符串,所以这⾥使⽤printf来打印  printf("pc+1 = %p\n", pc + 1);  printf("pi = %p\n", pi);  printf("pi+1 = %p\n", pi + 1);  return 0;  
}

![[Pasted image 20250314211030.png]]

char* 类型的指针变量 +1 跳过 1 个字节, int* 类型的指针变量 +1 跳过了 4 个字节。这就是指针变量的类型差异带来的变化。指针 +1 ,其实跳过 1 个指针指向的元素。指针可以 +1 ,那也可以 -1
结论:指针的类型决定了指针向前或者向后⾛⼀步有多⼤(距离)

void*指针

在指针类型中有⼀种特殊的类型是 void * 类型的,可以理解为⽆具体类型的指针(或者叫泛型指针),这种类型的指针可以⽤来接受任意类型地址。但是也有局限性, void* 类型的指针不能直接进⾏指针的±整数和解引⽤的运算。

#include <cstdio>  
int main()  
{  int a = 10;  int* pa = &a;char* pc = &a;  return 0;  
}

在上⾯的代码中,将⼀个int类型的变量的地址赋值给⼀个 char* 类型的指针变量。编译器给出了⼀个报错(如下图),是因为类型不兼容。⽽使⽤ void* 类型就不会有这样的问题
![[Pasted image 20250314211357.png]]

#include <cstdio>  
int main()  
{  int a = 10;  void* pa = &a;  void* pc = &a;  *pa = 10;  *pc = 0;  return 0;  
}

![[Pasted image 20250314211425.png]]

void* 类型的指针可以接收不同类型的地址,但是⽆法直接进⾏指针运算

⼀般 void* 类型的指针是使⽤在函数参数的部分,⽤来接收不同类型数据的地址,这样的设计可以实现泛型编程的效果。

void test(void* p)  
{  //....  
}  int main()  
{  int a = 10;  test(&a);  double d = 3.14;  test(&d);  return 0;  
}

指针访问数组

有⼀个整型数组,10个元素,默认初始化为0,现在要将数组的内容设置为1~10,然后打印数组的内容。
我们可以使⽤数组的形式,来完成任务,也可以使⽤指针的形式来完成。
我们知道数组在内存中是连续存放的,那是只要给定⼀个起始位置,顺藤摸⽠就能到后边的其他元素了。下⾯我们来使⽤指针,给⼀个整型数组做⼀个初始化,再将数组的内容打印出来。
![[Pasted image 20250314211542.png]]

#include <iostream>  
using namespace std;  
int main()  
{  int arr[10] = {0};  int *p = &arr[0];  int i = 0;  for(i = 0; i < 10; i++)  {  *(p + i) = i + 1;  }  for(i = 0; i < 10; i++)  {  cout << *p << " ";  p++;  }  return 0;  
}

![[Pasted image 20250314211643.png]]

  1. 这⾥操作的是整型数组,我们写代码时期望以⼀个整型为单位的访问,解引⽤时访问⼀个整型,+1 跳过⼀个整型,所以我们使⽤了 int* 类型的指针,如果是其他类型的数据要选择最恰当的指针类型。
  2. 代码中第⼀个 for 循环,我们选择使⽤ p+i 的⽅式, p 不变, i 在不断地变化,找到数组的每个元素,第⼆个 for 循环,我们选择 p++ 的效果,让 p 不断地往后寻找元素,要体会这两种的差异。
  3. 我们在代码中使⽤ for 循环,通过元素个数控制循环的次数。其实指针就是地址,是⼀串编号,这个编号是有⼤⼩的,那就可以⽐较⼤⼩,这就是指针的关系运算。使⽤指针关系运算,也能完成上⾯代码。请看下⽅代码:
#include <iostream>  
using namespace std;  
int main()  
{  int arr[10] = {0};  int *p = &arr[0];  int i = 0;  for(i = 0; i < 10; i++)  {  *(p + i) = i + 1;  }  while(p < &arr[10])  {  cout << *p << " ";  p++;  }  return 0;  
}

![[Pasted image 20250314211808.png]]

动态内存管理

变量的创建会为变量申请⼀块内存空间,数组的创建其实也向内存申请⼀块连续的内存空间。

int n = 10; //向内存申请4个字节的空间  
char arr1[5]; //向内存申请5个字节的空间  
int arr2[5]; //向内存申请20个字节的空间

这两种⽅式,如果创建是全局的变量和数组,是在内存的静态区(数据段)申请的,如果是局部的变量和数组,是在内存的栈区申请的。不管是全局变量还是局部变量,申请和回收都是系统⾃动完成的,不需要程序员⾃⼰处理。

#include <iostream>  
using namespace std;  
//全局变量 - 存放在内存的静态区(数据段)  
int n2 = 10;  
int arr2[5];  
int main()  
{  //局部变量 - 存放在内存的栈区  int n1 = 10;  int arr1[5];  return 0;  
}

其实C++还提供了另外⼀种⽅式,就是:动态内存管理,允许程序员在适当的时候,⾃⼰申请空间,⾃⼰释放空间,⾃主维护这块空间的⽣命周期。动态内存管理所开辟到的空间是在内存的堆区。

new/delete

C++中通过 new 和 delete 操作符进⾏动态内存管理。

  • new 负责申请内存, new 操作符返回的是申请到的内存空间的起始地址,需要指针存放。
    • new申请⼀个变量的空间, new[] 申请⼀个数组的空间
  • delete 负责释放(回收)内存
    • delete 负责释放⼀个变量的空间, delete[] 释放⼀个数组的空间
  • new 和 delete 配对, new[]delete[] 配对使⽤
// 动态申请⼀个int类型的空间  
int* ptr1 = new int;  
// 动态申请⼀个int类型的空间并初始化为10  
int* ptr2 = new int(10);  
// 动态申请10个int类型的空间  
int* ptr3 = new int[10];  
//释放内存空间  
delete ptr1;  
delete ptr2;  
delete[] ptr3;

![[Pasted image 20250314212407.png]]

new 不是只能给内置类型开辟空间,也可以给⾃定义类型开辟空间

#include <iostream>  
using namespace std;  
int main()  
{  int*p = new int;  *p = 20;  cout << *p << endl;  delete p;  int *ptr = new int[10];  for(int i = 0; i < 10; i++)  {  *(ptr + i) = i;  }  for(int i = 0; i < 10; i++)  {  cout << *(ptr + i) << " ";  }delete[] ptr;  return 0;  
}

其实数组是连续的空间, new[]申请到的空间也是连续的,那上述代码中 ptr 指向的空间能不能使⽤数组的形式访问呢?答案是可以的,上⾯代码中第18⾏代码可以换成:

cout << ptr[i] << " ";

文章转载自:

http://R7yxD0J2.mrtdq.cn
http://C1lGga9x.mrtdq.cn
http://p1uEHAZz.mrtdq.cn
http://O3YqIIg1.mrtdq.cn
http://wbrqLDbB.mrtdq.cn
http://7444JPQh.mrtdq.cn
http://pWdJXcHL.mrtdq.cn
http://yw8sGJpg.mrtdq.cn
http://i3H1PCFf.mrtdq.cn
http://Q2R8feef.mrtdq.cn
http://GPytmu8v.mrtdq.cn
http://RuBEERdD.mrtdq.cn
http://dXqvDJ8f.mrtdq.cn
http://co5XwKBz.mrtdq.cn
http://F64TMtOH.mrtdq.cn
http://wV0a7ALS.mrtdq.cn
http://zc7mMfms.mrtdq.cn
http://QCOO0Q0E.mrtdq.cn
http://k8tgd1FQ.mrtdq.cn
http://BnCxsqWi.mrtdq.cn
http://fxqAtS1Z.mrtdq.cn
http://SGUG4fF3.mrtdq.cn
http://IgnlOSHs.mrtdq.cn
http://MCRb71jA.mrtdq.cn
http://ODktDElA.mrtdq.cn
http://1AY6NSeQ.mrtdq.cn
http://MZgHDj1H.mrtdq.cn
http://EbrX2dN6.mrtdq.cn
http://Q0EOyk3S.mrtdq.cn
http://QgXb06mt.mrtdq.cn
http://www.dtcms.com/wzjs/713968.html

相关文章:

  • 动漫网站开发合肥网站维护
  • 做短视频网站用哪家cms昌平电子网站建设
  • 网站建设哪家做的好一点广告创意设计竞赛
  • 广州seo网站公司做外贸在哪个网站好
  • 常见的网站首页布局有哪几种ipv6网站开发
  • PHP网站开发常用函数婚庆公司简介
  • 企业网站栏目设计淄博网站建设推广优化
  • 熊猫网站ppt网站要怎么做的
  • 丰富网站内容wordpress购物 app
  • 网站运营做阿里巴巴网站电话
  • 有源代码怎么做网站网站怎么推广
  • eclipse 简单网站开发wordpress电商主题免费
  • 网站后台系统功能wordpress注册邮件怎么设置
  • 无锡做网站6建设公司网站标题
  • 环球网河北seo推广平台
  • 综合性门户网站有哪些网站做推广的方式
  • 福州建设高端网站餐饮装修
  • 个人做网站需要注意什么php网站开发 知乎
  • 提供网站制作公司电话河北住房建设厅官方网站
  • 郑州网站建设目标建设外卖网站需要哪些资质
  • 网站建设流程是这样的 里面有很wordpress上传打文件失败
  • 网站建设中下载国内品牌营销成功案例
  • 网站建设技术质量指标新浪微舆情大数据平台
  • 南昌做网站哪家专业服装企业网站模板
  • 用云速成美站怎么做网站wordpress仿站开发
  • 美容行业网站建设方案wordpress如何二次开发
  • 镇江网站建设制作公司做网站运营话术
  • 网站右侧浮动移动应用开发专业
  • 设计制作一个网站免费服务器搭建网站详细教程
  • 官网站内优化怎么做wordpress+积分+文章