昨天和赵崇说了一下工作的事情,说起了性能问题就讨论起了数据结果和指针对性能的影响。曾经一直没有想到这方面的事情,这几天专门抽时间回想一下这方面的知识,然后一点一点的总结一下,看看数据结构和指针在咱们代码中是怎样实现效率的提升的。

今天咱们先说一下指针。关于指针,在学C++的时候到时接触过指针。可是当时学的云里雾里,也没能好好的总结一下,以至于忘的差点儿相同了,假设大家也有对指针不熟悉的地方。我们先来回想一下C++的指针吧。

在C++中。指针是这样子定义的:指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。

要搞清一个指针须要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区。还有指针本身所占领的内存区。让我们分别说明。

int *ptr;
char *ptr;
int **ptr;
int (*ptr)[3];
int *(*ptr)[4];

通过上边的样例。大家把指针的申明语法去了。剩下的就是指针了。所以上边的指针就是“ptr”。

然后我们看一下指针的类型:

int *ptr; //指针的类型是int *
char *ptr; //指针的类型是char *
int **ptr; //指针的类型是 int **
int (*ptr)[3]; //指针的类型是 int(*)[3]
int *(*ptr)[4]; //指针的类型是 int *(*)[4]

怎么样?找出指针的类型的方法是不是非常easy?

指针所指向的类型

当你通过指针来訪问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。

指针所指向的类型

int *ptr; //指针的类型是int
char *ptr; //指针的类型是char
int **ptr; //指针的类型是 int *
int (*ptr)[3]; //指针的类型是 int()[3]
int *(*ptr)[4]; //指针的类型是 int *()[4]

指针的值

这个须要看操作系统,假设咱们的系统是32位的。那么咱们的指针就是32位长度的一个值,由于计算机的内存长度是32位。同理,64位的就是64位长度的值,当然这个64和32。都是用0和1表示的,由于计算机仅仅能知道0和1.

指针所指向的内存区就是从指针的值所代表的那个内存地址開始,长度为sizeof(指针所指向的类型)的一片内存区。

以后,我们说一个指针的值是XX。就相当于说该指针指向了以XX为首地址的一片内存区域。我们说一个指针指向了某块内存区域。就相当于说该指针的值是这块内存区域的首地址。

运算符&和*

这里&是取地址运算符,*是...书上叫做“间接运算符”。

&a的运算结果是一个指针。指针的类型是a的类型加个*(比如int*)。指针所指向的类型是a的类型(int)。指针所指向的地址嘛。那就是a的地址。

*p的运算结果就五花八门了。

总之*p的结果是p所指向的东西。这个东西有这些特点:它的类型是p指向的类型。它所占用的地址是p所指向的地址。

说过来翻过去。就是一个咱们手机导航过程。a就是你家,&a是指向你家的地址,比如p=&a,那么p就是我家的地址。那么*p的*就相当于咱们手机的导航过。通过你输入的地址,来找到你家。

上边的样例,仅仅是简单的说了一下什么叫做地址。那么假设大家想要更深层次的理解指针的话。给大家推荐一篇博客,写的很的基础http://www.cnblogs.com/basilwang/archive/2010/09/20/1831493.html

那么为什么要有指针呢,如不你设计一个函数

struct get(){

.........

}

返回一个结构体对象的函数,你要知道,C++中,这种返回值都是复制传递的过程。也就是说,你返回这个结构体的时候,程序会复制一个一样的结构体对象在栈里面,然后接受的变量在通过拷贝构造函数,复制一个新的变量。

最后程序在析构掉这个暂时的。

假设结构体非常小。没什么问题,假设非常大呢?这样一构造,一析构,会非常浪费时间。可是指针就不一样了,管你怎么弄,反正就是4字节。和一个int一样,全然没差别。

那么接下来咱们说一下C++到C#的”进化史”吧,平时我们见的代码好像没有再像C++的代码用到了指针,后来人们就说微软是不是就没有指针。事实上微软是有的,大家右击咱们的解决方式下的类库-à生成à不安全代码,大家勾选一下啊,一样能够用。仅仅只是写类和方法的时候前边加上个一个unsafe。比如:

public partial unsafe class Demostatic unsafe void Copy(byte[] src, int srcIndex,byte[] dst, int dstIndex, int count){//。。。。。
}

另一个keyword要注意,那就是Fixed。他的作用就是一个钉子,大家看了上边的介绍会发现指针事实上也是计算机中的0和1。

指针也占用内存。仅仅是他的大小是固定的。

而fixed语句可用于设置指向托管变量的指针并在 statement 运行期间“钉住”该变量。假设没有 fixed语句。则指向可移动托管变量的指针的地址可变。由于垃圾回收可能不可预知地重定位变量。

C# 编译器仅仅同意在 fixed语句中分配指向托管变量的指针,但无法改动在 fixed 语句中初始化的指针。

能够用数组或字符串的地址初始化指针:

fixed (int* p = arr) ...  // equivalent to p = &arr[0]
fixed (char* p = str) ... // equivalent to p = &str[0]

下边为大家呈现一个完整的样例,一个C#使用指针的样例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace cursorTest
{class Program{// 使用unsafe标注该方法static unsafe void Copy(byte[] src, int srcIndex,byte[] dst, int dstIndex, int count){if (src == null || srcIndex < 0 ||dst == null || dstIndex < 0 || count < 0){throw new ArgumentException();}int srcLen = src.Length;int dstLen = dst.Length;if (srcLen - srcIndex < count ||dstLen - dstIndex < count){throw new ArgumentException();}// 用fixed钉住指针。不让他改变     fixed (byte* pSrc = src, pDst = dst){byte* ps = pSrc;byte* pd = pDst;// 循环复制for (int n = 0; n < count / 4; n++){*((int*)pd) = *((int*)ps);pd += 4;ps += 4;}//完毕赋值for (int n = 0; n < count % 4; n++){*pd = *ps;pd++;ps++;}}}static void Main(string[] args){byte[] a = new byte[100];byte[] b = new byte[100];for (int i = 0; i < 100; ++i)a[i] = (byte)i;Copy(a, 0, b, 0, 100);Console.WriteLine("The first 10 elements are:");for (int i = 0; i < 10; ++i)Console.Write(b[i] + " ");Console.WriteLine("\n");Console.ReadLine();}}
}

可是为什么我们的代码如今都不怎么用指针呢,由于在公共语言执行库 (CLR) 中,不安全代码是指无法验证的代码。C# 中的不安全代码不一定是危急的,仅仅是其安全性无法由 CLR进行验证的代码。

因此。CLR 仅仅对在全然受信任的程序集中的不安全代码运行操作。假设使用不安全代码。由您负责确保您的代码不会引起安全风险或指针错误。所以你假设对你的代码很有保证的话,用也是没问题的。

C++和C#的指针小解相关推荐

  1. MIT 6.s081学习笔记

    MIT 6.s081学习笔记 introduction 计算机组织结构: 最底部是一些硬件资源,包括了CPU,内存,磁盘,网卡 最上层会运行各种应用程序,比如vim,shell等,这些就是正在运行的所 ...

  2. 杨辉三角超详细小解三种方法--《Blind-Stab》

    杨辉三角,是二项式系数在三角形中的一种几何排列.在欧洲,这个表叫做帕斯卡三角形.帕斯卡(1623----1662)是在1654年发现这一规律的,比杨辉要迟393年,比贾宪迟600年.杨辉三角是中国古代 ...

  3. Go 知识点(19)— Go 语言中的野指针

    野指针是一种指向内存位置是不可知的指针,一般是由于指针变量在声明时没有初始化所导致的.在 Go语言中,布尔类型的零值为 false,数值类型的零值为 0,字符串类型的零值为 "", ...

  4. C++ 笔记(27)— 指针变量、数组和指针、指针数组、数组指针、指针常量与常量指针

    1. 什么是指针变量? 指针变量是专门有一个变量来存放指针. int main(int argc, char *argv[]) {int a = 10;int *p = &a; //通过取地址 ...

  5. Go 学习笔记(71)— Go 接口 interface (接口定义、接口实现、接口调用、值接收者、指针接收者)

    1. 接口的定义 接口是和调用方的一种约定,它是一个高度抽象的类型,不用和具体的实现细节绑定在一起.接口要做的是定义好约定,告诉调用方自己可以做什么,但不用知道它的内部实现,这和我们见到的具体的类型如 ...

  6. Go 学习笔记(70)— Go 变量声明、变量初始化、值类型变量赋值、指针类型变量赋值

    1. 变量声明 要单纯声明一个变量,可以通过 var 关键字,如下所示: var s string 该示例只是声明了一个变量 s,类型为 string,并没有对它进行初始化,所以它的值为 string ...

  7. c/c++中的函数指针和指针函数

    定义 1.指针函数,本质是函数,返回值为指针,形如,int *pfun(int, int),由于"*"的优先级低于"()"的优先级,所以等同于int *(pfu ...

  8. 关于C语言中的数组指针、指针数组以及二级指针

    概念解释 数组指针:首先它是一个指针,它指向一个数组,即指向数组的指针:在32 位系统下永远是占4 个字节,至于它指向的数组占多少字节,不知道.数组指针指向的是数组中的一个具体元素,而不是整个数组,所 ...

  9. 【数据结构】链表中的 指针,地址

    数据结构中跳过集合,直接开始线性结构 线性结构中单链表的操作涉及到给一个变量赋值地址,所以涉及到了指针 通过指针里的地址很方便找到节点 但指针这里绕了我很长时间,不论学了多少遍也不敢说把指针学会了 地 ...

最新文章

  1. 库克说AI也能创造很多就业岗位,苹果加码教育布局
  2. SD VC - 变式价格
  3. 万字长文带你看尽深度学习中的各种卷积网络
  4. python编程培训多少钱-线下python培训要多少钱?
  5. php中的unbuffered_row,php – 加载数据infile和unbuffered查询错误
  6. 为什么说PHP是很糟糕的,也是很好的编程语言
  7. c语言从键盘输入asdfg输出asdfg,C语言复习题参考答案.doc
  8. python-DBSCAN密度聚类
  9. Java线程面试题TOP50
  10. scikit-learn——快速入门
  11. ehcache常用API整理
  12. 用友发布智多星 AI 企业大脑,其核心组成原来是这样的
  13. js每隔5分钟执行一次ajax请求的实现方法
  14. 安卓输入法 车机版_触宝输入法HD
  15. 全球最大的电子图书馆创世纪下载网址
  16. 香橙派 Orangepi Zero2 外壳天线改装
  17. python三重积分_(整理)三重积分及其计算和多重积分72254.
  18. 颈椎护理小助手,轻松缓解颈部酸痛,宾多康智能颈枕按摩器体验
  19. 家庭组网 光猫+交换机利用VLAN划分实现客厅单线复用(下) 将各房间网口接入家庭局域网
  20. vue2.0学习——使用webstorm创建一个vue项目

热门文章

  1. 项目复审——Beta阶段
  2. Maven deploy部署jar到远程私服仓库
  3. 微信小程序 开发过程中遇到的坑(一)
  4. Python基础-包
  5. 从0开始学Java——JSPServlet——HttpServletRequest相关的几个路径信息
  6. 关于重写equals()与hashCode()
  7. Java基础---网络编程
  8. asp.net mvc批量删除的实现
  9. DOMContentLoaded与interactive
  10. 我也来记录我的一些开发心得和笔记!