C++和C#的指针小解

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

今天咱们先说一下指针。关于指针,在学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位长度的值,当然这个6432。都是用01表示的,由于计算机仅仅能知道01.

     指针所指向的内存区就是从指针的值所代表的那个内存地址開始,长度为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。他的作用就是一个钉子,大家看了上边的介绍会发现指针事实上也是计算机中的01

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

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



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281624.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用RoleBasedAuthorization实现基于用户角色的访问权限控制

本文将介绍如何通过 Sang.AspNetCore.RoleBasedAuthorization[1] 库实现 RBAC 权限管理。使用介绍Step 1添加库 Sang.AspNetCore.RoleBasedAuthorizationInstall-Package Sang.AspNetCore.RoleBasedAuthorizationStep 2在 Program.cs 中添加builder.Services.AddSangRoleBasedA…

【2018-11-15】中证1000指数的估值详情

中证1000指数选取中证500和沪深300指数样本股以外的&#xff0c;流动性好的1000只股票组成&#xff0c;与沪深300 和中证500 等形成互补。 中证1000的个股大多数是由市场上流通市值排名在 800 到 1800 名之间的个股组成&#xff0c;是一个适用范围较广的小盘指数。 中证1000的…

[Leetcode Week15]Populating Next Right Pointers in Each Node

Populating Next Right Pointers in Each Node 题解 原创文章&#xff0c;拒绝转载 题目来源&#xff1a;https://leetcode.com/problems/populating-next-right-pointers-in-each-node/description/ Description Given a binary tree struct TreeLinkNode {TreeLinkNode *left…

php 数组 1 开始,php数组使用1

1、array_values($arr) 将数组转换成索引数组$arr1 [id>10,name>杨过,sex>male,salary>8900];echo .var_export(array_values($arr1),true).;2、array_column($arr,$col,$boll); 获取多维数组的列表组成的数组。$arr2 [];$arr2 [[id>10,name>杨过,sex>…

印度光伏巨头Adani与华为签署500MW采购合同

日前&#xff0c;印度光伏巨头Adani与华为签订了采购合同。Adani未来一年的项目全部采用华为FusionSolar3.0智能光伏解决方案&#xff0c;首期500MW采购合同已经签署&#xff0c;将采购最新的智能光伏控制器&#xff08;组串逆变器&#xff09;SUN2000-43KTL、数据采集器SmartL…

宣布 .NET MAUI 支持 .NET 7 RC 2

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;6分钟)支持 .NET 7 Release Candidate 2 的 .NET 多平台应用程序 UI (MAUI) 现在可在 Windows 和 Mac 上的 Visual Studio 17.4 Preview 4 中使用。RC2 的主要主题是质量和对带有 iOS 16 的 Xcode 14 的 .NET 支持。此…

linux c文件操作,Linux C 文件的输入/输出操作

10.1 文件I/O操作概述在Linux系统中&#xff0c;文件I/O操作可以分为两类&#xff0c;一类是基于文件描述符的I/O操作&#xff0c;另一类是基于数据流的I/O操作。10.1.1 文件描述符简介在文件操作一章中&#xff0c;也经常提到文件描述符这个概念。所谓文件描述符&#xff0c;就…

个人中心标签页导航

新页面userbase.html,用<ul ><li role"presentation"> 实现标签页导航。<ul class"nav nav-tabs"> <li role"presentation"><a href"#">Home</a></li> <li role"presentation&qu…

智慧城市免费WiFi覆盖怎么实施?武邑开启智慧生活模式

“真没想到武邑这个国家级贫困县也能够随地使用无线网络&#xff0c;我初次考察就喜欢上了这里。”准备前来武邑县投资的客商王先生说。日前&#xff0c;随着县城广场、商场等公共场所的免费WiFi覆盖&#xff0c;及移动电子商务借势O2O的快速发展&#xff0c;衡水市武邑县正在逐…

Uno开发的小游戏

大家好&#xff0c;我是沙漠尽头的狼。刚在微信群里逛&#xff0c;有网友发了Uno的在线小游戏&#xff0c;站长觉得不错&#xff0c;简单分享下&#xff1a;群聊涨见识Uno是什么&#xff1f;使用 C# 和 WinUI 实现像素完美的多平台应用程序&#xff0c;用于构建适用于 Windows、…

sqlplus命令行登录oracle数据库的N种方法盘点

欢迎访问我的个人博客IT废柴&#xff0c;本文永久链接移至&#xff1a;sqlplus命令行登录oracle数据库的N种方法盘点 sqlplus有几种登陆方式Oracle数据库&#xff0c; 比如&#xff1a; 1.以操作系统权限认证的oracle sys管理员登陆 C: > sqlplus "/as sysdba" 2…

拉美光伏新兴市场热潮将至

国际油价下滑对油气生产国的影响是不言而喻的&#xff0c;受此拖累&#xff0c;可再生能源产业发展也承受了一定压力。然而&#xff0c;在多国拥有油气资源的拉美地区&#xff0c;情况却恰恰相反&#xff0c;许多国家的可再生能源产业非但没有受低油价拖累&#xff0c;反而快速…

linux下常见生产脚本,不看后悔的Linux生产服务器Shell脚本分享(2)

一、MySQL的热备份脚本这是MySQL的备份方式之一&#xff0c;脚本如下&#xff1a;#!/bin/bashPATH/usr/local/sbin:/usr/bin:/bin# The Directory of BackupBACKDIR/usr/mysql_backup# The Password of MySQLROOTPASSpassword# Remake the Directory of Backuprm -rf $BACKDIRm…

兄弟连学python——MongoDB相关

1.常用的命令 show dbs 显示数据库列表use dbname 进入dbname数据库&#xff0c;大小写敏感&#xff0c;没有这个数据库也不要紧show collections 显示数据库中的集合&#xff0c;相当于表格2.创建&新增 db.users.save({"name":"lecaf"}) …

WPF-12 路由事件之二

WPF 为我们提供了许多不同的事件处理机制——它们是冒泡、隧道和直接的。这些都称为路由事件直接事件直接在事件源上处理&#xff0c;这个有点像WinForms中的按钮OnClick事件&#xff0c;直接在事件处理程序中处理业务冒泡事件当事件没有被元素&#xff08;比如一个文本框&…

对01背包的分析与理解(图文)

首先谢谢Christal_R的文章(点击转到链接)让我学会01背包 本文较长&#xff0c;但是长也意味着比较详细&#xff0c;希望您可以耐心读完。 题目: 现在有一个背包(容器),它的体积(容量)为V,现在有N种物品(每个物品只有一个),每个物品的价值W[i]和占用空间C[i]都会由输入给出,现在…

linux内核源码剖析 博客,【Linux内存源码分析】页面迁移

页面迁移其实是伙伴管理算法中的一部分&#xff0c;鉴于其特殊性&#xff0c;特地另行分析。它是2007年的时候&#xff0c;2.6.24内核版本开发时&#xff0c;新增碎片减少策略(the fragmentation reduction strategy)所引入的。该策略也称之为反碎片技术(anti-gragmentation)。…

360的下一代SOC是这个样子的

几乎所有大型企业或机构的IT系统中&#xff0c;都会有安全运营中心(SOC)&#xff0c;它是网络安全防护体系从设备部署到系统建设&#xff0c;再到统一管理&#xff0c;这一发展过程的自然产物。但在国内的实际应用中&#xff0c;SOC的问题多多。 首先是数据类型不全&#xff0c…

【转载】利用scipy.misc等库对jpg以及png等图像数据预处理(用于深度学习喂数据)...

http://blog.csdn.net/qq_16949707/article/details/56306720 转载于:https://www.cnblogs.com/tenderwx/p/8057599.html

2018年下半年网络公式考试案例分析真题

阅读以下说明&#xff0c;回答问题1至问题3&#xff0c;将解答填入答题纸对应的解答栏内。【说明】某公司网络划分为两个子网&#xff0c;其中设备A是DHCP服务器&#xff0c;如图3-1所示。 【问题1】(6分&#xff0c;每空2分)DHCP在分配IP地址时使用 (1) 的方式&#xff0c; 而…