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.pswp.cn/news/281624.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/281624.shtml
英文地址,請注明出處:http://en.pswp.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; 而…