C語言【指針1】

来源:https://www.cnblogs.com/wangsiyaoa/archive/2023/11/22/17850058.html
-Advertisement-
Play Games

Zlib是一個開源的數據壓縮庫,提供了一種通用的數據壓縮和解壓縮演算法。它最初由`Jean-Loup Gailly`和`Mark Adler`開發,旨在成為一個高效、輕量級的壓縮庫,其被廣泛應用於許多領域,包括網路通信、文件壓縮、資料庫系統等。其壓縮演算法是基於`DEFLATE`演算法,這是一種無損數據壓... ...


C語言【指針1】

1、指針類型長度隨操作系統,64位操作系統為8Byte。

​ 具體說一下:地址相當於門牌號,一般一個地址指向的空間是一個位元組(下麵按一個位元組敘述,電腦底層也許也有按雙位元組編碼的)。對於64位機器,某一個地址有64位,所以在空間里存那某一個地址時,這64位即8Byte。這64位總共能表示的數量(即定址數量)為2^64,十六進位0x0000000000000000到0xffffffffffffffff,這個數很大很大,以現在的記憶體空間來看,如果一個地址指向的空間是1Byte,根本用不完。

2、 %p為輸出指針的占位符;&為取址運算符;*為取值運算符(即取地址對應的數據)。
3、指針一些基礎知識,以代碼為例。
int a = 100;
/** 	
*	下麵的代碼是聲明並初始化。
*	之後想要改變指針指向,要修改p而不是*p(這裡聲明並初始化時用*p是指明定義的是一個指針)。
*	之後想要改變變數a的值,修改*p即可。
*/
int* p = &a;	
*p = 200;	// 修改*p時,a也會跟著改變
printf("%p\n", &a);	//	輸出a的地址
printf("%p\n", p);	//	輸出a的地址
printf("%d\n", a);	//	輸出a的值
printf("%d\n", *p);	//	輸出a的值
printf("%p\n", &p);	//	輸出p的地址。p本身也有地址指向它,它也是個空間,空間里存的地址。

​ 指針就是個變數,存的別的數據地址,如果存自己的地址,那沒啥意義。

​ 指針就是個變數,它是p而不是* p。* p是那個數據,參考上面代碼。

​ 數組名、函數名等就是地址本身(或者說是表示數組或函數首地址的常量),所以,可以通過數組名給指針的方式使指針指向數組,反之不行,數組名和函數名不可更改。

/**
*	如果把指針賦給普通整型變數,可以。但如果想像*指針一樣給這個變數加 * ,就不行了。
*/
int a = 100;
int * p = &a;
long long la = p;
*la;	// 會報錯。
/**
* 不同指針類型
*/
int a = 100;
int* p = &a;
double * p1 = p;	// p1和p空間里的位元組數一樣,但去a那找的寬度不一樣。* p1 去a那要找8Byte.
/**
* 野指針問題
*/
int * p;	// 一個野指針
*p = 100;	// 如果p是在函數里定義的,直接修改隨機指向里的值,不會報錯,但可能使程式崩掉。

指針的運算,即地址的運算,只不過指針可以接收運算的結果,而地址不行

​ 1.指針(地址)只能和整數作加減運算(包括兩地址相加減)。本質就是地址的運算,指針可以接收結果。
對於int類型的指針來說,p+=1即p往後(高位)移動了4個位元組。其他類型同理。

​ 2.同類型指針相減,得到一個ptrdiff_t類型的數據。其占位符為 %td 。

int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *p1 = &arr[0];	// int * p1 = arr;
int *p2 = &arr[3];	// int * p2 = arr+3;   
p1[2];	// 等同arr[2] 指定數組後,指針可以這樣使用
p2[2];	// arr[5], 看第三行代碼
printf("%td\n", p1 - p2);	// -3  兩地址相差3,(自動除過int的位元組數)

​ 3.指針(地址)也可以作比較運算。棧先進後出,所以在函數中,一般先初始化的放在高地址,指針指向的時候可比較指向變數的地址大小。

4、指針和數組名的區別與共用。
  • 區別

    指針是變數,數組名是常量。

    sizeof(數組名) 返回為整個數組的位元組數;當指針指向數組後,sizeof(指針) 返回仍然是跟隨系統的位元組數。

  • 相同。數組除了不能隨意修改或指向外,基本可以當指針使用;當指針指向數組後,指針可以使用數組的所有方式操作數組。舉個例子:

    int arr[20] = {10, 20, 30, ...};
    printf("%d\n", (arr+1)[0]);	// 20。 這裡arr+1並沒有修改arr的值。這個(arr+1)[0]可替換為*(arr+1).
    
5、指針數組。int *p[10]; 指針數組是一個大數組,裡面存放的是一個個的指針。

​ * p[1] 和*(p[1])是一樣的。表示第二個數組元素中指針指向的數值。

int a = 10, b = 20;
int *p[2] = {&a, &b};
printf("%d %d\n", *p[0], *p[1]);	// 10 20
6、數組指針。int (*p)[10]; 數組指針是一個指針,裡面存放了一個數組。[10]表示這個二維的p加一就跳10個長度。這裡這個p是一個二維的指針。
int (*p)[3];	// p+1即跳3個元素
int arr[2][3] = {1, 2, 3, 4, 5, 6};
p = arr;		// 這裡是二維的,就不加&了
printf("%d\n", (*(p+1))[0]);	// 跳三個加個*再取數組第一個元素
補一個案例
int a = 256;
int* p = &a;  
// int* p = &a + 1;  // 這裡+1的話也是加了4返回給p
long long p1 = p;	// 這裡就是為了下麵可以加真實的數,而不是加定義類型的倍數
p = p1+1;			// 真正的+1 而不是+4
*p = 10;
printf("%d\n", a);	// 2560   湊巧10倍了
printf("%d\n", *p);	// 10

// 這個程式就是往左移了一個位元組再改數,回到之前的變數輸出混亂的值。
再補一個
int arr[5] = {10, 20, 30, 40, 50};
int (*ptr1)[5] = &arr;
printf("%d\n", ptr1 == arr);	// 1   但警報,不報錯
printf("%d\n", *ptr1 == arr);	// 1
printf("%d\n", ptr1+1 == arr+1); //0   arr+1是第二個元素的地址, ptr1+1 越界了,就不可能等了

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 您是否曾經希望擁有一個神奇的工具包,可以讓您像超級英雄一樣控制 JavaScript 對象?向ReflectAPI 打個招呼吧,它是 ES6 中引入的一個新的全局對象 ,它能夠處理簡單的代碼操作。它是每個現代 JavaScript 開發人員都需要的瑞士軍刀!📜 本文的目標是幫助您更好地理解 ...
  • 所謂天才,就是努力的力量。 React 組件由 DOM 結構,樣式和 Javascript 邏輯組成。 1. ES6 中的類 class People { constructor() { this.name = "hubert" this.age = 29 } printName() { conso ...
  • 我們在剛開始架構設計時手足無措,但是隨著我們完成一個又一個的系統架構設計以後,發現架構設計是有章法可循的,只要我們學習這些章法和套路,並且在工作過程中不斷的積累與沉澱,就會行成一個完整的架構設計方法論,面對新的大型系統架構設計,也會一步一步有節奏進行,最終完成整體的架構設計 ...
  • JUC的強大輔助類 juc中提供了常用的輔助類,通過這些輔助類,可以很好的解決線程數量過多時,Lock鎖的頻繁操作這三種輔助類為: 1.CountDownLatch,減少計數。 2.CyclicBarrier,迴圈柵欄。 3.Semaphore,信號燈。 減少計數器(CountDownLatch) ...
  • 十三、指針和引用(三) 1、std::unique_ptr(唯一智能指針) 1)概念 std::unique_ptr是所謂的智能指針的一種,主要目的是為瞭解決原生指針安全性不足的弊端 //std::unique_ptr指針的聲明語法 std::unqiue_ptr<類型>變數名稱{}; //示例 s ...
  • 背景及問題: 目前很多區域網設備通過mNDS協議實現互聯,IP地址為自動IP段-169.254.x.x,有時候設備廠家提供的API需要通過知曉區域網中的IP地址/設備名,才能連接該設備。這樣要求每個軟體必須配置設備名或者啟動時遍歷所有IP(6w+),不是很方便,這時候可以通過mDNS查詢,自動拿到設 ...
  • 第一章 電腦系統概述 “較簡單,不做過多贅述,後面會詳細學到” 第一節 電腦系統層次結構 1.電腦系統的基本組成:硬體+軟體 2.電腦硬體的基本組成:運算器+存儲器+控制器+輸入設備+輸出設備 3.系統軟體和應用軟體 系統軟體 操作系統、資料庫管理系統、語言處理程式、分散式軟體系統、網路軟體 ...
  • [HD2016.X1] 價錢統計 題目描述 夏天到了,超市裡擺滿了各種各樣的應季水果。現在知道:西瓜的價錢是每斤 1.2 元;桃子的價錢是每斤 3.5 元;葡萄的價錢是每斤 4.5 元;蘋果的價錢是每斤 5 元。 現在分別給出上述四種所購買的斤數(均不超過 20),請你編寫程式幫助售貨員阿姨計算並依 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...