C語言中的指針

来源:http://www.cnblogs.com/dengxiangliu/archive/2016/12/30/6235479.html
-Advertisement-
Play Games

1、什麼是指針? 指針就是地址。 為了說清楚什麼是指針,必須先弄清楚數據在記憶體中是如何存儲的,又是如何讀取的。 如果在程式中定義了一個變數,在對程式進行編譯時,系統就會給這個變數分配記憶體單元。編譯系統根據程式中定義的變數的類型,分配一定長度的空間。 記憶體區的每一個位元組都會有一個編號,這就是“地址”, ...


1、什麼是指針?

指針就是地址。

為了說清楚什麼是指針,必須先弄清楚數據在記憶體中是如何存儲的,又是如何讀取的。

如果在程式中定義了一個變數,在對程式進行編譯時,系統就會給這個變數分配記憶體單元。編譯系統根據程式中定義的變數的類型,分配一定長度的空間。

記憶體區的每一個位元組都會有一個編號,這就是“地址”,它相當於旅館中的房間號,在地址所標誌的記憶體單元中存放的數據則相當於旅館房間中居住的旅客。

一個變數的地址,稱為該變數的指針。

2、指針變數

(1)、存放地址的變數就叫指針變數。

(2)、定義指針變數的一般形式為:類型名 *指針變數名;     例如:int * pointer_1;

(3)、指針變數前面的“*”表示該變數的類型為指針類型。

(4)、一個變數的指針的含義包括兩個方面:一是以存儲單元編號表示的地址;二是它指向的存儲單元的數據類型。

(5)、如何表示指針類型。指向整型數據的指針類型表示為“int *”,讀作:指向int的指針或int 指針。

2.1、如何引用指針變數

(1)、給指針變數賦值

int a =10;
int *p;//定義一個指針變數 p
p=&a;//把a的地址賦給指針變數p

指針變數p的值是變數a的地址,p指向a;

(2)、引用指針變數指向的變數

printf("%d\n",*p);//輸出變數a的值

(3)、引用指針變數的值

printf("%o\n",p);//以八進位形式輸出變數a的地址,即指針變數p的值

註意:(1)、& 取地址運算符。&a是變數a的地址。   (2)、*指針運算符。

3、通過指針引用數組

(1)、數組元素的指針

1、一個變數有地址,一個數組包含若幹個元素,每個數組元素都在記憶體中占用著記憶體單元,它們都有相應的地址。指針變數既可以指向變數,當然也可以指向數組元素。所謂數組元素的指針其實就是數組元素的地址。

2、引用數組元素有兩種方法:(1)、下標法;(2)、指針法。

3、註意:數組名不代表整個數組,只代表數組的首地址,

(2)、在引用數組元素時指針的運算

在指針指向數組元素時,我們可以進行如下運算:

int a[10];
int *p;
p =&a;//等價於p=&a[0]

1、p+1則指向a[1],即p指向了數組元素中的一個元素,則p+1則指向數組元素中的下一個元素,p-1則指向數組元素中的上一個元素。

2、如果p的初始值為&a[0],則p+i和a+i就是數組元素a[i]的地址。也就是說p+i和a+i指向a數組序號為i的元素。註意:這裡說的a代表的是數組首元素的地址。

3、*(p+i)和*(a+i)是p+i和a+i所指向的數組元素,即a[i]。

(3)、通過指針引用數組元素

通過指針引用數組元素,有2種方法:

1、下標法:

#include <stdio.h>

int main(int argc,char **argv)
{
       int a[10];
        int i;
        printf("Please input 10 integer numbers: ");
        for(i=0;i<10;i++)
        {
             scanf("%d",&a[i]);
        }     
        for(i=0;i<10;i++)
        {
              printf("%d\n",a[i]);
        }      
        return 0;
}       

2、指針法

(1)、通過數組名計算數組元素的地址,找出元素的值。

#include<stdio.h>

int main(int argc,char *argv[])
{
    int a[10];
    int i;
    printf("Please input 10 integer numbers: ");
    for(i=0;i<10;i++)
    {
         scanf("%d",&a[i]);
    }  
    for(i=0;i<10;i++)
    {
         printf("%d",*(a+i));
    }
     printf("\n");
    return 0;
}

(2)、用指針變數指向數組元素

#include<stdio.h>

int main(int argc,char *argv[])
{
    int a[10];
    int i;
    int *p;
    printf("Please input 10 integer numbers: ");
    for(i=0;i<10;i++)
    {
         scanf("%d",&a[i]);
    }  
    for(p=a;p<(a+10);p++)
    {
         printf("%d",*p);
    }
     printf("\n");
    return 0;
}

(4)、用數組名作函數參數

int main()
{
    void fun(int arr[],int n);//對fun函數的聲明
    int array[10];//定義array數組
      .
      .
      .
     fun(array,10);//用數組名做函數的參數
    return 0;
}

//定義fun函數
void fun(int arr[],int n)
{
   ....
}

array是實參數組名,arr為形參數組名。當用數組名作形參時,如果形參數組中各元素的值發生變化,實參數組元素的值隨之變化。為什麼會這樣呢?

在該函數被調用時,系統會在fun函數中建立一個指針變數arr,用來存放從主調函數傳遞過來的實參數組首元素的地址。

當arr接收了實參數組的首元素地址後,arr就指向實參數組首元素,也就是指向array[0]。因此,*arr就是array[0]。arr+1指向array[1],arr+2指向array[2],arr+3指向array[3]。也就是說:*(arr+1)、*(arr+2)、*(arr+3)分別是array[1]、array[2]、array[3]。

C語言調用函數時虛實結合的方法都是採用“值傳遞”方式,當用變數名作為函數參數時傳遞的是變數的值,當用數組名作為函數參數時,有於數組名代表的是數組首元素地址,因此傳遞的值是地址,所以要求形參為指針變數。

(5)、通過指針引用多維數組 

指針變數可以指向一維數組中的元素,也可以指向多維數組中的元素。 

 

4、通過指針引用字元串

(1)、字元串的引用方式

(2)、字元指針作函數參數

(3)、使用字元指針變數和字元數組的比較

5、指向函數的指針

(1)、什麼是函數指針?

如果在程式中定義了一個函數,在編譯時,編譯系統為函數代碼分配一段存儲空間,這段存儲空間的起始地址(又稱入口地址)稱為這個函數的指針。

可以定義一個指向函數的指針變數,用來存放某一函數的起始地址,這就意味著此指針變數指向該函數,例如:

int (*p)(int ,int);

定義p是一個指向函數的指針變數,它可以指向函數的類型為整形且有兩個整型參數的函數。p的類型用int (*)(int int)表示。

在這裡我們得瞭解一下指針函數與函數指針的區別

(2)、用函數指針變數調用函數

(3)、怎樣定義和使用指向函數的指針變數

(4)、用指向函數的指針作函數參數

6、返回指針值的函數

7、指針數組和多重指針

(1)、什麼是指針數組

(2)、指向指針數據的指針

(3)、指針數組作main函數的參數

1、int main()

int main(void)

 括弧中是空的或有"void",表示main函數沒有參數,調用main函數時不必給出實參。

2、int main(int argc,char *argv[])

其中argc和argv就是main函數的參數,它們是程式的“命令行參數”。

argc(argument count的縮寫,意思是參數個數);

argv(argument vector的縮寫,意思是參數向量),它是一個*char 指針數組,數組中每一個元素(其值為指針),指向命令行中的一個字元串。

-----------------------------------------------

8、動態記憶體分配與指向它的指針變數

(1)、什麼是記憶體的動態分配

(2)、怎樣建立記憶體的動態分配

(3)、void指針類型

9、有關指針的小結

 


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

-Advertisement-
Play Games
更多相關文章
  • 2016年11月,接受了一個工作,是對“悟空CRM”進行一些修補。這是一個不錯的 CRM,開源,並提供一個 SaaS 的服務。正好微軟的 .NET Core 和 ASP.NET Core 也發佈了。於是就有了這個想法:使用 ASP.NET Core 來開發一個 CRM。當然這裡面的私心是:朝後坦白講 ...
  • 效果: 方法一: View: 註:"f_GroupID"相當於name="f_GroupID",我用的是KendoUI的Grid,所以name="f_GroupID"綁定的是kendo的schema的 f_GroupID Controller: 實體: 方法二: View: Controller: ...
  • Xamarin與VisualStudio2015離線安裝包打包方法介紹,以及最後分享打包好的離線包在百度網盤https://pan.baidu.com/s/1o8pWvBO(7Zip解壓)。幫助大伙擺脫無法正常安裝Xamarin開發環境的苦惱。 ...
  • 屬性註入不同於通過構造函數方式傳入參數. 這裡是通過註入的方式, 在類創建完畢之後, 資源釋放之前, 給屬性賦值. 這裡, 我重新弄一些類來演示這一篇吧. 1. 一般方法 這種方法, 不止可以註入屬性, 還可以給欄位賦值 2. 反射的方式 這裡需要註意一點, 由於ClassC中有ClassD格式的屬 ...
  • demo:https://github.com/dunitian/DNTLive/tree/master/Software/WaterMarkAPP/LoTWaterAPP 說起這個人臉識別,還真有點緣分。記得逆天以前在學生時代參加創新大賽的時候,題目就是人臉識別打卡 解決別人替人打卡的問題,想想看 ...
  • 看過我WPF 微信 MVVM這篇文章的朋友,應該知道我裡面提到了我有一個小號是無法獲取列表的,始終也沒找到原因。 前兩天經過GitHub上h4dex大神的指導,知道了原因,是因為微信在登錄以後,web微信採取了不同的功能變數名稱來相容各種用戶。 下麵是大神提供的js代碼和C#代碼 function () { ...
  • 今日問題: 請問主程式輸出結果是什麼?(點擊以下“【Java每日一題】20161230”查看20161229問題解析) 題目原發佈於公眾號、簡書:【Java每日一題】20161230,【Java每日一題】20161230 註:weknow團隊近期開通並認證了分答,歡迎大家收聽,有問題也歡迎到分答來咨 ...
  • 一、方法函數 函數也稱為方法,就是定義在類中的具有特定功能的一段獨立代碼。用於定義功能,提高代碼的復用性。 函數的特點1> 定義函數可以將功能代碼進行封裝,便於對該功能進行復用;2> 函數只有被調用才會被執行;3> 對於函數沒有具體返回值的情況,返回值類型用關鍵字void表示,那麼該函數中的retu ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...