最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

老生常談C語言中指針的使用

 更新時間:2022年02月21日 09:23:32   作者:紙墨青鳶  
這篇文章主要為大家詳細介紹了C語言中指針的使用,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

前提

指針,是C語言中的一個重要概念及其特點,也是掌握C語言比較困難的部分。指針也就是內(nèi)存地址,指針變量是用來存放內(nèi)存地址的變量,在同一CPU構架下,不同類型的指針變量所占用的存儲單元長度是相同的,而存放數(shù)據(jù)的變量因數(shù)據(jù)的類型不同,所占用的存儲空間長度也不同。有了指針以后,不僅可以對數(shù)據(jù)本身,也可以對存儲數(shù)據(jù)的變量地址進行操作

指針描述了數(shù)據(jù)在內(nèi)存中的位置,標示了一個占據(jù)存儲空間的實體,在這一段空間起始位置的相對距離值。在 C/C++語言中,指針一般被認為是指針變量,指針變量的內(nèi)容存儲的是其指向的對象的首地址,指向的對象可以是變量(指針變量也是變量),數(shù)組,函數(shù)等占據(jù)存儲空間的實體。

一.指針基礎

1.1 變量指針

//首先我們聲明一個變量
int a = 10;	//聲明一個指針并指向該變量的地址	
int* b = &a;	printf("%d\n", *b);

運行結果:10

1.2 數(shù)據(jù)指針

//首先我們聲明一個數(shù)組變量
int c[10] = { 0,1,2,3,4,5,6,7,8,9 };		
printf("c的地址:%p\n", c);	
printf("c[0]的地址:%p\n", &c[0]);

運行結果:兩個一樣

Why? 數(shù)組本質為內(nèi)存空間上連續(xù)的空間,而作為數(shù)組的地址,其實為首元素的地址,而對于數(shù)組,數(shù)組名稱其實就是個指針(重點)然后我們創(chuàng)建數(shù)組指針

int* d=c
printf("d[9]的值為:%d\n",*(d+9));
//另一種寫法printf("d[9]的值為:%d\n",d[9]);

運行結果:9

1.3 指針的本質

通過1.0和1.1的指示我們突然發(fā)現(xiàn),整數(shù)的指針和整數(shù)數(shù)組的指針居然是同個類型!

事實上確實是一個東西,指針為指向變量地址的類型,所以對于指針來說是不需要類型的,但是為了程序規(guī)范性,增加了類型說法

下面使用無類型指針輸出a的值(10)

void* p = &a;
printf("void指針的值:%d\n", *(int*)p);
//對比b指針變量
printf("這是b的值:%p\n", b);
printf("這是p的值:%p\n", p);

在這里插入圖片描述

上述結果可以完全表明,指針變量儲存的是地址,而且是單一變量的地址

接下來可以解釋數(shù)組和數(shù)為啥指針就是同一個類型了

回到1.2所述 單個數(shù)占了1個空間(這里不提占用內(nèi)存),而數(shù)組占了n個空間,而指針指向的都是首地址,而對于單個數(shù)來說

首地址就是數(shù)所在的地址,而對于數(shù)組來說,首地址就是頭元素所在的地址

1.2解釋了數(shù)組地址就是數(shù)組名本身,所以數(shù)組指針就是數(shù)組本身了,所以有下面這種寫法

printf("直接使用數(shù)組名獲取索引3的元素:%d\n", c[3]);
printf("使用指向c的指針獲取索引3的元素:%d\n", d[3]);

在這里插入圖片描述

但是數(shù)組和指針數(shù)組還是有一定的區(qū)別

1.4 指針數(shù)組

/如果我們把指針看作一個變量,那么類比整數(shù)類型,我們一定可以聲明一個指向指針的指針

int g = 50;
int* h = &g;
int** i = &h;
//輸出一下
printf("h的值:%p\n", h);
printf("i的值:%p\n", *i);
//實驗證明這是可行的,那我們嘗試做一個數(shù)組
int j[5] = { 9,8,7,6,5 };
int* k[5] = { &j[0],&j[1],&j[2],&j[3],&j[4] };
int** l = k;
printf("k[1]的值:%p,對應的整數(shù)的值:%d\n", k[1], *k[1]);
printf("l獲取k1的值:%p,對應的整數(shù)的值:%d\n", *(l + 1), **(l + 1));

在這里插入圖片描述

這就是指針數(shù)組,把指針當作一個變量看,指針也可以做數(shù)組

1.5 指針的移動

對于數(shù)組指針獲取元素,上面展示了可以通過"變量名[索引]"的方式獲取,當然也可以通過移動指針位置來獲取

int* m = (int*)malloc(10 * sizeof(int));
for (int i = 0; i < 10; ++i)
	*(m++) = i;

指針移動到了分配內(nèi)存的最后一塊

“變量名[索引]“的方式表明了是以當前指針為數(shù)組頭,偏移索引個單位為方法獲取元素的方式,索引獲取第8個元素

錯誤寫法 printf(”%d”,m[8]);

正確寫法

printf("%d\n", *(m - 2));

在這里插入圖片描述

所以釋放的時候要釋放頭指針,所以要回到頭指針

for (int i = 0; i < 10; ++i)
	(--m);
free(m);

所以實際操作的情況下盡量不要去移動指針

int* n = (int*)malloc(10 * sizeof(int));
for (int i = 0; i < 10; ++i)
	*(n + i) = i;
printf("%d\n", *(n + 8));
free(n);

在這里插入圖片描述

1.5 Scanf函數(shù)的解釋

scanf函數(shù)為獲取變量地址函數(shù)

首先我們看一下scanf函數(shù)的定義

scanf函數(shù)有一個格式符參數(shù)和一個可變參數(shù)

可變參數(shù)類型為指針?。。?!

char o;

第一種直接寫法

scanf("%c", &o);

printf(“輸出的字符:%c\n”, o);

同理

用指針獲取

char* q = &o;
scanf("%c", q);
printf("通過指針獲取輸出的字符:%c\n", *q);

在這里插入圖片描述

上面我們說了,指針可以代表數(shù)組,而c語言對字符串的定義就是字符數(shù)組

char r[] = { "Hello" };
scanf("%s", r);
printf("字符串的值:%s\n", r);

這樣我們就可以解釋為什么對于獲取字符串的時候,不用寫&的原因了,因為字符數(shù)組本來就是指針!!

二.指針的進階玩法

2.1 二維指針

由名字可得,二維指針就是指針的指針,指針可以代表數(shù)組,自然二維指針就可以代表二維數(shù)組

int u[4][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6},{4,5,6,7} };
int** v = u;

二維數(shù)組在內(nèi)存空間上也是線性排列的,就如下順序

1 2 3 4 2 3 4 5 3 4 5 6 4 5 6 7

所以二維數(shù)組獲取元素也可以靠指針移動

printf("u[1][2]的值:%d\n", *(v + 6));

也可以動態(tài)內(nèi)存分配實現(xiàn)

int** w = (int**)malloc(4 * sizeof(int)); //分配行內(nèi)存
for (int i = 0; i < 4; ++i)
	w[i] = (int*)malloc(4 * sizeof(int)); //分配列內(nèi)存
for (int i = 0; i < 4; ++i)
	for (int j = 0; j < 4; ++j)
		w[i][j] = (j + 1) + i;
printf("w[1][2]的值:%d\n", w[1][2]);
free(w); //記得釋放

2.2 結構體指針

先聲明一個結構體

struct people
{
	char* name;
	int age;
}SPeople;
//方便表示替換掉標識符
typedef struct people People;
People dr;
dr.name = "aaa";
dr.age = 18;
printf("dr的名字是:%s,年齡是:%d\n", wusihao.name, wusihao.age);
People* lp = &wusihao; //注意屬性獲取的符號"->"
lp->name = "sss";
lp->age = 19;
printf("lp的名字是:%s,年齡是:%d\n", lp->name, lp->age);

當然也可以動態(tài)內(nèi)存分配使用

People* lps = (People*)malloc(1 * sizeof(People));
lps->name = "xxx";
lps->age = 20;
printf("lps的名字是:%s,年齡是:%d\n", lps->name, lps->age);

結語

指針定義后,在不用時最好指向NULL,比如

int* s = &a;
printf("%p\n", s);
s = NULL;

因為就算釋放掉內(nèi)存,但是指針指向的內(nèi)存地址依舊可用(獲取處于沉睡狀態(tài)),所以最好不要去動它,不然很容易導致內(nèi)存泄露

動態(tài)聲明的指針一定要釋放,free函數(shù)釋放

動態(tài)分配內(nèi)存最好要檢查是否成功分配到

int* t = (int*)malloc(10 * sizeof(int));
if (t == NULL)
{
	//分配錯誤
	system("pause");
	return 0;
}
else
{
	//你的代碼
	system("pause");
	free(t);
}

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內(nèi)容!     

相關文章

  • OpenCV + MFC實現(xiàn)簡單人臉識別

    OpenCV + MFC實現(xiàn)簡單人臉識別

    這篇文章主要為大家詳細介紹了OpenCV + MFC實現(xiàn)簡單人臉識別,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Qt?Qml實現(xiàn)任意角為圓角的矩形

    Qt?Qml實現(xiàn)任意角為圓角的矩形

    在?Qml?中,矩形(Rectangle)是最常用的元素之一,本文將介紹如何通過自定義?Qml?元素實現(xiàn)一個任意角可為圓角的矩形,感興趣的可以了解下
    2025-01-01
  • C++ vector容器縮小capacity問題

    C++ vector容器縮小capacity問題

    這篇文章主要介紹了C++ vector容器縮小capacity問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • MFC程序設計常用技巧匯總

    MFC程序設計常用技巧匯總

    這篇文章主要介紹了MFC程序設計常用技巧,實例匯總了MFC程序設計中常見的問題與解決方法,非常具有實用價值,需要的朋友可以參考下
    2015-05-05
  • C語言版的三子棋游戲

    C語言版的三子棋游戲

    這篇文章主要為大家詳細介紹了C語言版的三子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C++迭代器失效解決辦法詳解

    C++迭代器失效解決辦法詳解

    這篇文章主要介紹了迭代器失效的概念,以及在vector、list和map等容器中插入和刪除操作導致迭代器失效的情況,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-12-12
  • C語言實現(xiàn)的一個萬年歷小程序

    C語言實現(xiàn)的一個萬年歷小程序

    這篇文章主要介紹了C語言實現(xiàn)的一個萬年歷小程序,具有一定的參考價值,做C語言日期計算的朋友可以參考下
    2014-07-07
  • 基于Matlab實現(xiàn)中國象棋的示例代碼

    基于Matlab實現(xiàn)中國象棋的示例代碼

    中國象棋是起源于中國的一種棋,屬于二人對抗性游戲的一種,在中國有著悠久的歷史。由于用具簡單,趣味性強,成為流行極為廣泛的棋藝活動。本文將利用Matlab實現(xiàn)這一游戲,需要的可以參考一下
    2022-02-02
  • 詳解Qt中QStackedWidget控件的使用

    詳解Qt中QStackedWidget控件的使用

    這篇文章主要為大家詳細介紹了Qt中QStackedWidget控件的具體使用,文中的示例代碼講解詳細,具有一定的借鑒價值,需要的可以參考一下
    2023-02-02
  • C++淺析內(nèi)存分區(qū)模型概念與示例

    C++淺析內(nèi)存分區(qū)模型概念與示例

    在了解內(nèi)存分區(qū)之前,我們先來聊一聊為什么要進行內(nèi)存分區(qū)。在進行了內(nèi)存分區(qū)之后,在不同的區(qū)域存放的數(shù)據(jù),會有不同的生命周期,從而會讓程序員的編程變得更加靈活
    2022-09-09

最新評論

永定县| 连山| 龙井市| 盐亭县| 分宜县| 通道| 宣恩县| 松原市| 柳江县| 高陵县| 常州市| 上栗县| 成都市| 黄大仙区| 双峰县| 上林县| 玉林市| 商丘市| 册亨县| 油尖旺区| 拉孜县| 叙永县| 本溪| 慈溪市| 右玉县| 吴忠市| 盈江县| 定远县| 托里县| 永顺县| 牙克石市| 孝义市| 资中县| 昌邑市| 东城区| 梅州市| 唐河县| 乌什县| 广元市| 昌黎县| 射洪县|