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

C語言指針之必須要掌握的指針基礎(chǔ)知識

 更新時(shí)間:2021年09月26日 14:54:39   作者:程序里的酒  
這篇文章主要介紹了C語言指針必須要掌握的基礎(chǔ)知識,文中實(shí)例講解的很清晰,有不太懂的同學(xué)可以研究下,希望能夠給你帶來幫助

一、指針概述

指針是個(gè)變量,存放內(nèi)存單元的地址(編號)。

指針的創(chuàng)建

在定義指針變量的時(shí)候,在變量前面加上' * ',代表這個(gè)變量是一個(gè)指針,再往前面加上一個(gè)類型名,就代表指針的類型,稱為XX指針。

指針的初始化:

使用&(取地址操作符)可以獲得變量的地址,將其賦值給已經(jīng)定義好的指針變量,需要它們的類型相同,類型不同的時(shí)候可以使用強(qiáng)制轉(zhuǎn)換。如果暫時(shí)不知道需要存放什么地址的時(shí)候,可以先讓它指向NULL((void*)0),NULL本質(zhì)就是0,0這個(gè)地址是不允許存儲的。

#include <stdio.h>
int main()
{
	int a = 10;//在內(nèi)存中開辟一塊空間
	int *p = &a;//這里我們對變量a,取出它的地址,可以使用&操作符。
				//將a的地址存放在p變量中,p就是一個(gè)指針變量。
	return 0;
}

指針的大小

指針可以是不同的類型,char*、int*、float*、double*、long*等我們熟知的類型,那指針在內(nèi)存中占多大的空間呢?

對于32位的機(jī)器,假設(shè)有32根地址線,那么假設(shè)每根地址線在尋址的是產(chǎn)生一個(gè)電信號正電/負(fù)電(1或者0)
那么32根地址線產(chǎn)生的地址就會是:

00000000 00000000 00000000 00000000
……
111111111 111111111 111111111 111111111
共有232個(gè)地址,每一個(gè)地址能指向一個(gè)內(nèi)存單元(一字節(jié)),那么有232個(gè)內(nèi)存單元。

我們知道一個(gè)內(nèi)存單元的大小為一字節(jié),一根地址線是32位01組成的,那么要存放指針(地址),也就需要32個(gè)bit,也即4字節(jié)。所以在32位平臺下不論是什么類型的指針都是4個(gè)字節(jié)。

同理,在64位平臺下有64根地址線,每個(gè)地址是64位,所以需要8個(gè)字節(jié)。

如何使用指針

使用' * '操作符對指針進(jìn)行解引用,可以獲取到指針指向空間的值

我們來運(yùn)行下方代碼。

#include <stdio.h>
int main()
{
	int n = 0x11223344;
	char* pc = (char*)&n;//將n的地址(指針)強(qiáng)制轉(zhuǎn)換成char* 類型
	int* pi = &n;
	*pc = 0;//改變它指向空間的值
	*pi = 0;
	return 0;
}

我們開始調(diào)試代碼,查看n的內(nèi)存,最左邊是地址,右邊是以16進(jìn)制顯示內(nèi)存里存放的數(shù)據(jù),而n也是以16進(jìn)制存進(jìn)去的,兩個(gè)16進(jìn)制代表一個(gè)字節(jié),如下圖:

在這里插入圖片描述

當(dāng)執(zhí)行完語句 *pc=0;

在這里插入圖片描述

因?yàn)閜c指向的是char* 類型,只能訪問一個(gè)字節(jié),所以只能修改一個(gè)字節(jié)。

再執(zhí)行*pi = 0;

在這里插入圖片描述

此時(shí)n的內(nèi)存數(shù)據(jù)全部變成了0,說明int*類型的指針可以訪問4個(gè)字節(jié)。

小結(jié):

指針的類型決定了,對指針解引用的時(shí)候有多大的權(quán)限(能操作幾個(gè)節(jié))。 比如: char* 的指針解引用就只能訪問一個(gè)字節(jié),而 int* 的指針的解引用就能訪問四個(gè)字節(jié)。

二級指針

指針變量也是變量,是變量就有地址,那指針變量的地址存放在哪里? 這就是 二級指針 。
即存放指針變量的地址的指針,二級指針指向的空間的值是一個(gè)一級指針。

int main()
{
	int a = 20;
	int* p = &a;
	int** pp = &p;
	printf("%d\n", *p);//解引用即可拿到指針指向空間里面的值
	printf("%d\n", *p); //對二級指針,需要兩次解引用才能拿到最開始的值
	return 0;
}

在這里插入圖片描述

在這里插入圖片描述

二、野指針

野指針就是指針指向的位置是不可知的(隨機(jī)的、不正確的、沒有明確限制的)。

形成野指針的原因

1.指針未初始化

#include <stdio.h>
int main()
{
	int *p;//局部變量指針未初始化,默認(rèn)為隨機(jī)值
	*p = 20;//往一個(gè)隨機(jī)的地址(不屬于本程序的空間)里面放入數(shù)據(jù),是不允許的
	return 0;
}

2.指針越界訪問

指針想要訪問不屬于本程序的空間,造成越界訪問,程序出錯(cuò),在使用數(shù)組的時(shí)候最容易發(fā)生。

#include <stdio.h>
int main()
{
	int arr[10] = {0};
	int *p = arr;
	int i = 0;
    for(i=0; i<=11; i++)
	{
  		//當(dāng)指針指向的范圍超出數(shù)組arr的范圍時(shí),p就是野指針
    	*(p++) = i;
	}
	return 0;
}

3.指針指向的空間釋放

當(dāng)動態(tài)開辟的內(nèi)存被釋放后,此時(shí)的指針就屬于野指針,它指向的位置它不能正常訪問。關(guān)于動態(tài)內(nèi)存分配,后續(xù)會細(xì)講。

int main()
{
	//開辟一個(gè)整形空間
	int* p = (int*)malloc(sizeof(int));
	//釋放該空間
	free(p);
	//此時(shí)p即為野指針,因?yàn)樗赶虻目臻g已經(jīng)無法訪問,一般需要將其置空
	//將其指向空指針,防止后續(xù)調(diào)用出錯(cuò)
	p = NULL;
	return 0;
}

如何規(guī)避野指針

  • 指針初始化
  • 小心指針越界
  • 指針指向空間釋放即使置NULL
  • 指針使用之前檢查有效性

三、指針的基本運(yùn)算

關(guān)于指針的運(yùn)算一般有兩個(gè),指針+指針,語義是合法,但沒有意義。

  • 指針± 整數(shù)
  • 指針-指針

指針± 整數(shù)

對int和char類型的指針分別進(jìn)行+1操作,%p以16進(jìn)制打印

int main()
{
	int n = 10;
	char* pc = (char*)&n;//將n的地址(指針)強(qiáng)制轉(zhuǎn)換成char* 類型
	int* pi = &n;
	printf("&n:    %p\n", &n);
	printf("pc:    %p\n", pc);
	printf("pc + 1:%p\n", pc + 1);
	printf("pi:    %p\n", pi);
	printf("pi + 1:%p\n", pi + 1);
	return 0;
}

在這里插入圖片描述

小結(jié):

指針的類型決定了指針向前或者向后走一步有多大(距離)。

指針-指針

int main()
{
	int n = 10;
	char* pc = (char*)&n;//將n的地址(指針)強(qiáng)制轉(zhuǎn)換成char* 類型
	int* pi = &n;
	printf("&n:    %p\n", &n);
	printf("pc:    %p\n", pc);
	printf("pc + 1:%p\n", pc + 1);
	printf("pi:    %p\n", pi);
	printf("pi + 1:%p\n", pi + 1);
	return 0;
}

在這里插入圖片描述

小結(jié):

指針-指針等于它們之間相差的類型數(shù)據(jù)的個(gè)數(shù)。即本例的第10個(gè)元素和第1個(gè)元素之間相差9。

四、指針和數(shù)組

一起來看一下數(shù)組名是什么

#include <stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	return 0;
}

在這里插入圖片描述

可見數(shù)組名和數(shù)組首元素的地址是一樣的。

結(jié)論: 數(shù)組名表示的是數(shù)組首元素的地址。也是一個(gè)指針

那么我們就可以用一個(gè)指針來代替數(shù)組名,如下代碼:

int main()
{
	int arr[10] = { 0 };
	int* p = arr;
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);//計(jì)算數(shù)組元素個(gè)數(shù)
	//對數(shù)組賦值
	for (i = 0; i < sz; i++)
	{
		*(p + i) = i;
	}
	//打印數(shù)組數(shù)據(jù)
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));
	}
	return 0;
}

在這里插入圖片描述

注意:

數(shù)組名在下面兩種情況下不是首元素的地址

1.sizeof(數(shù)組名) - 這里的數(shù)組名不是首元素的地址,是表示整個(gè)數(shù)組的,這里計(jì)算的是整個(gè)數(shù)組的大小,單位還是字節(jié)

2.&數(shù)組名 - 這里的數(shù)組名不是首元素的地址,是表示整個(gè)數(shù)組的,拿到的是整個(gè)數(shù)組的地址

int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr);
	printf("sizeof(arr)計(jì)算的是整個(gè)數(shù)組的大?。?d\n", sz);
	printf("數(shù)組首地址:      %p\n", arr);
	printf("數(shù)組首元素地址:  %p\n", &arr[0]);
	printf("數(shù)組的地址:      %p\n", &arr);
	printf("數(shù)組首地址+1:    %p\n", arr + 1);
	printf("數(shù)組首元素地址+1:%p\n", &arr[0] + 1);
	printf("數(shù)組的地址+1:    %p\n", &arr + 1);
	//數(shù)組名確實(shí)是首元素的地址
	//但是有2個(gè)例外:
	//1. sizeof(數(shù)組名)  - 這里的數(shù)組名不是首元素的地址,是表示整個(gè)數(shù)組的,這里計(jì)算的是整個(gè)數(shù)組的大小,單位還是字節(jié)
	//2. &數(shù)組名 - 這里的數(shù)組名不是首元素的地址,是表示整個(gè)數(shù)組的,拿到的是整個(gè)數(shù)組的地址
	//
	return 0;
}

在這里插入圖片描述

五、指針數(shù)組

存放指針的數(shù)組。

int main()
{
	int a = 1;
	int b = 2;
	int c = 3;
	int* arr[10] = { &a,&b,&c };
	for (int i = 0; i < 3 ; i++)
	{
		printf("%d ", *(arr[i]));
	}
	return 0;
}

在這里插入圖片描述

總結(jié)

指針是C語言非常重要的一部分,內(nèi)容繁多不易懂,本文僅介紹了一些基本知識,后續(xù)還會深入了解指針。

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

相關(guān)文章

  • C++中生成隨機(jī)數(shù)的方法總結(jié)

    C++中生成隨機(jī)數(shù)的方法總結(jié)

    這篇文章主要介紹了C++中生成隨機(jī)數(shù)的方法總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • C++ TinyXML解析案例詳解

    C++ TinyXML解析案例詳解

    這篇文章主要介紹了C++ TinyXML解析案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C++多線程基礎(chǔ)理論詳解

    C++多線程基礎(chǔ)理論詳解

    這篇文章主要介紹了C++多線程基礎(chǔ)理論,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 基于C語言字符串函數(shù)的一些使用心得

    基于C語言字符串函數(shù)的一些使用心得

    以下是對C語言中字符串函數(shù)的一些使用心得進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下
    2013-08-08
  • 詳解C/C++性能優(yōu)化背后的方法論TMAM

    詳解C/C++性能優(yōu)化背后的方法論TMAM

    開發(fā)過程中我們多少都會關(guān)注服務(wù)的性能,然而性能優(yōu)化是相對比較困難,往往需要多輪優(yōu)化、測試,屬于費(fèi)時(shí)費(fèi)力,有時(shí)候還未必有好的效果。但是如果有較好的性能優(yōu)化方法指導(dǎo)、工具輔助分析可以幫助我們快速發(fā)現(xiàn)性能瓶頸所在,針對性地進(jìn)行優(yōu)化,可以事半功倍
    2021-06-06
  • 簡單解讀C++中的虛函數(shù)

    簡單解讀C++中的虛函數(shù)

    這篇文章主要介紹了C++中的虛函數(shù),在C++中,虛函數(shù)聯(lián)系到多態(tài)、多態(tài)聯(lián)系到繼承,因而虛函數(shù)是C++中的一大重要特性,需要的朋友可以參考下
    2016-04-04
  • C語言學(xué)習(xí)之標(biāo)識符的使用詳解

    C語言學(xué)習(xí)之標(biāo)識符的使用詳解

    C語言標(biāo)識符是用于表示變量、函數(shù)、常量、類型等程序元素的名稱,這篇文章將通過一些簡單的示例為大家介紹一下C語言標(biāo)識符的使用,需要的可以參考一下
    2023-05-05
  • C語言中的內(nèi)存管理之掌握動態(tài)分配的技巧(最新推薦)

    C語言中的內(nèi)存管理之掌握動態(tài)分配的技巧(最新推薦)

    在C語言編程中,內(nèi)存管理是一項(xiàng)至關(guān)重要的技能,它直接關(guān)系到程序的性能和穩(wěn)定性,特別是在處理大型數(shù)據(jù)集或需要靈活內(nèi)存布局的場景下,本文將深入探討C語言中的動態(tài)內(nèi)存分配技巧,幫助開發(fā)者更好地掌握這一核心技能
    2025-03-03
  • 使用mmap實(shí)現(xiàn)多進(jìn)程對大文件拷貝

    使用mmap實(shí)現(xiàn)多進(jìn)程對大文件拷貝

    這篇文章主要介紹了使用mmap實(shí)現(xiàn)多進(jìn)程對大文件拷貝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C語言位運(yùn)算符:與、或、異或、取反、左移與右移詳細(xì)介紹

    C語言位運(yùn)算符:與、或、異或、取反、左移與右移詳細(xì)介紹

    以下是對C語言中的位運(yùn)算符:與、或、異或、取反、左移與右移進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下
    2013-08-08

最新評論

肥乡县| 阳朔县| 乡宁县| 梧州市| 和硕县| 拉萨市| 海宁市| 涟水县| 玉屏| 汶川县| 上栗县| 乐亭县| 关岭| 且末县| 金乡县| 柘荣县| 思南县| 琼中| 诏安县| 彝良县| 乌审旗| 抚远县| 江阴市| 邳州市| 黔江区| 惠水县| 高邑县| 乳山市| 江安县| 莱西市| 静乐县| 吉木乃县| 波密县| 南和县| 榕江县| 澜沧| 华宁县| 浠水县| 信阳市| 莒南县| 惠来县|