欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言指針引用數(shù)組案例講解

 更新時間:2021年09月14日 08:50:27   作者:ty_77  
這篇文章主要介紹了C語言指針引用數(shù)組案例講解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下

前言:C語言中指針玩的是什么,是內(nèi)存,要想學(xué)好指針的小伙伴們要先對數(shù)據(jù)在內(nèi)存中是怎么玩的做一番了解~

      當在程序中定義一個變量時,系統(tǒng)會根據(jù)其數(shù)據(jù)類型為其開辟內(nèi)存空間,例如Visual C++為整型變量分配四個字節(jié)的空間,為單精度浮點型變量分配四個字節(jié),為字符型變量分配一個字節(jié),內(nèi)存中每個字節(jié)都有自己獨立且唯一的一個編號,這就是地址 ,如下圖,系統(tǒng)為變量i分配了2000~2004的存儲單元。

在這里插入圖片描述

_訪問變量的方式_有如下圖兩種:
第一種直接訪問方式,直接通過變量名訪問,變量名與地址有一一對應(yīng)關(guān)系,因此按此地址直接對變量i的存儲單元進行訪問;
第二種間接訪問方式,先通過i_pointer找到i的地址的位置,再通過i的所存地址的位置找到i的地址2000,隨后對變量i進行存取操作。間接訪問的方式就要用到指針,所謂指針(2000)即為一個變量的地址,指針變量(i_pointer)是存儲這個地址的用來指向另一個對象的變量。

關(guān)鍵字 變量類型
int 整型變量
char 字符變量
類型名* 指針變量

它們之間的關(guān)系為:指針變量的值是指針,指針是變量i的地址,變量i存放所需要存放的存儲內(nèi)容。
圖片的中*為取值運算符,*i_pointer表示對i_pointer中存放的地址進行取值,相當于 變量i。

在這里插入圖片描述

指針的定義:

基類型 *變量名
例:int *p
char *p
float p
注意 : 此時的
與上文中提到的取值運算符并不是一個概念,此時的
*意思是定義一個變量,這個變量是指針變量。

指針的引用:

對指針進行賦值:
以下面程序為例:

int *p;
int a = 3;
p = &a;
*p = 2;

p = &a(&為取地址符,意思是取變量a的地址賦給指針變量P)
*p = 2(p上文中已經(jīng)提到是對指針變量P中存儲的地址進行取值p相當于變量a,對
*p進行賦值即相當于對變量a進行賦值)

指針變量做函數(shù)參數(shù)

以定義兩個變量a和b,使其值進行交換為例進行闡述

#include<stdio.h>

//值傳遞
void swap1(int x, int y) {
	int z;
	z = x;
	x = y;
	y = z;
}

//地址傳遞 
void swap2(int *p1, int *p2) {
	int t = *p1;
	*p1 = *p2;
	*p2 = t;
}

/*
錯誤,指針變量t所指向的內(nèi)容不可預(yù)見,對*t賦值就是向一個未知存儲單元賦值 ,可能操縱到有用信息,
破壞系統(tǒng)的正常工作狀態(tài) ,這種指針叫做**野指針**;

那么如何解決野指針危險性呢:
可以對該指針進行初始化,使其指向NULL,NULL為地址為0的內(nèi)存地址,在大多數(shù)操作系統(tǒng)上,該內(nèi)存為操作系統(tǒng)保留,
用戶不可操控  
*/ 
//void swap3(int *p1, int *p2) {
//	int *t;
//	*t = *p1;
//	p1 = *p2;	//報錯 
//	p2 = *t;
//}

/*
C語言中實參變量與形參變量之間的數(shù)據(jù)傳遞是單向的“值傳遞”方式。
不能通過操作形參中指針變量的值企圖改變實參中指針變量的值,但是可以通過形參接收到的實參傳過來的地址
對指針變量指向的值進行操作。
*/ 
void swap4(int *p1, int *p2) {
	int *t = NULL;
	t = p1;
	p1 = p2;
	p2 = t;
}

int main() {
	int a, b;
	scanf("%d %d", &a, &b);
	
	swap1(a, b);
	printf("%d %d\n", a, b);
	
	int *p1 = &a, *p2 = &b;
	
	swap2(p1, p2);
	printf("%d %d\n", a, b);
	
	swap4(p1, p2);
	printf("%d %d\n", *p1, *p2);	//注:在swap2()函數(shù)中,a b的值發(fā)生了交換 
	
	return 0;	
}

/*
運行結(jié)果:
1 3
1 3
3 1
3 1
*/ 

指針指向數(shù)組

盆友們一定要記住這兩句話再往下看***?。?!***
首地址:一段內(nèi)存空間的第一個存儲單元,而不是第一個字節(jié);
指針變量的加減:以指針指向的類型空間為單元進行偏移;

以定義一個數(shù)組,輸入數(shù)值,最后輸出數(shù)組中所有元素為例進行闡述

/*
須知:
1.單目運算符優(yōu)先級比雙目運算符高,同級下從右往左結(jié)合 
2.*(p + i)等價于*(a+i)等價于a[i] 
3.數(shù)組名為數(shù)組的首地址,即p = a相當于p = &a[0]
4.p + 1指向數(shù)組中的下一個元素,加上的不是簡單的字節(jié)數(shù),而是定義的指針的基類型的字節(jié)數(shù)
5.a[i]的[]為變址運算符,下標法中對下標的處理是轉(zhuǎn)換成地址的,也是按照a + i計算地址,然后找出此地址單元中的值
6.利用p++的指針自加操作,指針直接指向元素,不必每次都計算地址,比下標法和計算指針地址后再取值的方法快 
7.a是一個類型為int *的指針常量,指向數(shù)組首個元素的地址,不能企圖使用a++的方式便利數(shù)組中的元素 
8.指針的加減運算往往作用在同一數(shù)組下的元素上,雖然指針變量可以指向數(shù)組元素以后的存儲單元,但是得到的數(shù)據(jù)往往是
不被我們所期待的數(shù)據(jù),這種操作是毫無意義的 
*/
#include<stdio.h>
int main() {
	int a[5];
	
	//下標法
	for(int i = 0; i < 5; i++) 
		scanf("%d", &a[i]);				//等價于scanf("%d", a + i);
	int *p, *p1;
	
	p = a;								//等價于p = &a[0] 
	p1 = &a[0];
	
	for(int i = 0; i < 5; i++)
		printf("%d ", a[i]);
	printf("\n");

	//指針法
	/*
	p:a[0]的地址	*p:a[0]的值
	*(p+1):a[1]的值
	*(p+2):a[2]的值 
	
	p的值并未改變 
	
	test: 
	#include<stdio.h>
	int main() {
		int a[5] = {1, 2, 3, 4, 5};
		int *p = a;
		printf("%d\n", p);
		for(int i = 0; i < 5; i++) {
			printf("%d ", *(p + i));
		}
		printf("\n%d\n", p);
		
		for(int i = 0; i < 5; i++) {
			printf("%d ", *p++);
		}
		printf("\n%d\n", p);
	} 
	/*
	運行結(jié)果:
	6618608
	1 2 3 4 5
	6618608
	6618628
	*/
	
	*/
			
	for(int i = 0; i < 5; i++) 
		printf("%d ", *(p + i));		
	printf("\n");
	
	//a為指針常量不能改變,變的是 a + i本身 
	for(int i = 0; i < 5; i++) 
		printf("%d ", *(a + i));		
	printf("\n");
	
	//指針p在不斷移動,因此在學(xué)習(xí)的過程中要時刻注意指針的位置?。?! 
	for(int p = a; p < (a + 5); p++)
		printf("%d ", *p); 
	return 0; 
}

/*
補充:
1.由于在C語言編程系統(tǒng)中,對下標的處理是轉(zhuǎn)換成地址的,因此, p[i]即被處理成*(p + i) 

數(shù)組名做函數(shù)參數(shù)

/*
須知:
1.數(shù)組名為數(shù)組首元素的地址,實參傳遞a傳遞給形參的是地址,形參需要用一個指針變量來接實參的地址
2.C編譯都是將形參數(shù)組名作為指針變量來處理的,也就是說,程序中形參的a[]的a實際上是一個指針,對a[]的操控實際上
就是對指向?qū)崊⒅械臄?shù)組進行操控
3.上文中已經(jīng)提到p[i]與*(p+i)無條件等價 
*/
#include<stdio.h>

void swap(int a[], int n) {
	int h = 0, t = n - 1, m = (n - 1) / 2;
	for(h; h <= m; h++) {
		int tmp = a[h];
		a[h] = a[t];		//根據(jù)須知3: a[h]等價于*(a+h) 
		a[t] = tmp;
		t--;
	}
}

void swap1(int *x, int n) {
	int *p, *i, *j;
	i = x;
	j = x + n - 1;
	p = x + (n - 1) / 2;

	for( ; i <= p; i++, j--) {
		int tmp = *i;
		*i = *j;
		*j = tmp;
	}
}

int main() {
	int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	for(int i = 0; i < 10; i++) 
		printf("%d ", a[i]);
	printf("\n"); 
	swap(a, 10);
	for(int i = 0; i < 10; i++) 
		printf("%d ", a[i]);
	printf("\n");
		
	swap1(a, 10);
	for(int i = 0; i < 10; i++) 
		printf("%d ", a[i]);
	printf("\n");
	return 0;	
} 
/*
運行結(jié)果:
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
*/ 

指針指向 二維數(shù)組

在這里插入圖片描述

a[3][4]數(shù)組的結(jié)構(gòu):
三個一維數(shù)組
四個int類型的元素

**
再次強調(diào):
1.指針變量的加減:以指針指向的類型空間為單元進行偏移;
2.數(shù)組名代表數(shù)組元素的首地址

a是二維數(shù)組名,指向的第一個存儲單元是a[0]這個一維數(shù)組,a的類型是指向一維數(shù)組的指針常量, a+1即偏移一個一維數(shù)組;
a[0],a[1], a[2]是一維數(shù)組名,代表一維數(shù)組中的元素的首地址,也就是說a[0]的值是&a[0][0],a[1]的值是&a[1][0],a[2]的值是&a[2][0]。    a[0],a[1], a[2]分別指向的第一個存儲單元是a[0][0], a[1][0], a[2][0]這幾個元素,它們的類型是指向元素的指針常量,a[0]+1即偏移一個元素;

為了讓大家看清除,博主以表格形式展示出來:

首地址 指向 類型 移動一位 移動字節(jié)數(shù)
二維數(shù)組的首地址a a[0]這個一維數(shù)組 int(*)[4] a+1 16B
以為數(shù)組的首地址a[0] a[0][0]元素 int* a[0]+1 4B

指針指向二維數(shù)組的各種表現(xiàn)形式

#include<stdio.h>
int main() {
	int a[3][4] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23};
	/*
	a是指向行的指針常量,代表二維數(shù)組的首地址,即首行的首地址,
	a + 1:序號為 1的行的首地址
	a + 2:序號為 2的行的首地址
	
	在行指針前面加一個 * ,則轉(zhuǎn)換成列指針(列地址),指向一維數(shù)組的首地址 ;


	*a:對第0行的地址進行取值,由于a并不是一個變量的存儲單元,取值后得到一維數(shù)組的地址a[0]<->*(a+0)<->*a,指向列地址,即第0行一維數(shù)組的首地址 
	*(a + 1): 第1行一維數(shù)組的首地址
	*(a + 2): 第2行一維數(shù)組的首地址 
	由于a[0] = *a, a[1] = *(a + 1), a[2] = *(a + 2),所以兩種形式等價 
	a[0]: 代表0行一維數(shù)組的首地址,指向0行0列元素地址 
	a[1]: 代表1行一維數(shù)組的首地址,指向1行0列元素地址 
	a[2]: 代表2行一維數(shù)組的首地址,指向2行0列元素地址 
	
	a[0] + 0: 代表0行0列元素的地址 
	a[0] + 1: 代表0行1列元素的地址
	a[0] + 2: 代表0行2列元素的地址 
	
	*(a[0] + 0): 0行0列元素的值,a[0][0],*(*(a + 0) + 0) 
	*(a[0] + 1): 0行1列元素的值,a[0][1], *(*(a + 0) + 1)
	*(a[0] + 2): 0行2列元素的值,a[0][2], *(*(a + 0) + 2)
	
	在列指針前面加一個 & , 則轉(zhuǎn)換成行指針(行地址),行指針前面加上一個 &,則轉(zhuǎn)換成指向整個數(shù)組的指針(表示為整個數(shù)組的地址),指向二維數(shù)組的首地址。 	
	&a: 指向整個二維數(shù)組 
	&a[0]: 指向第0行的一維數(shù)組 
	&a[0][0]: 指向0行0列的元素,即指向a[0][0], 是a[0][0]這個元素的地址 
	
	*/ 
	printf("%d %d\n", a, *a);			//a:表示0行首地址	  *a:表示0行0列元素的地址	二者的值一樣,但是指針類型不同					 
	printf("%d %d\n", a[0], *(a + 0));			 
	printf("%d %d\n", &a[0], &a[0][0]);	 
	printf("%d %d\n", a[1], a + 1);
	printf("%d %d\n", &a[1][0], *(a + 1) + 0);
	printf("%d %d\n", a[2], *(a + 2));
	printf("%d %d\n", &a[2], a + 2);
	printf("%d %d\n", a[1][0], *(*(a + 1) + 0));
	printf("%d %d\n", *a[2], *(*(a + 2) + 0));
	return 0;
}

/*
運行結(jié)果:
6618608 6618608
6618608 6618608
6618608 6618608
6618624 6618624
6618624 6618624
6618640 6618640
6618640 6618640
9 9
17 17
*/ 

指向二維數(shù)組的指針變量

#include<stdio.h>
int main() {
	int a[3][4] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23};
	
	/*
	指向數(shù)組元素的指針變量 
	*/ 
	int *p;
	for(p = a[0]; p < a[0] + 12; p++) {
		printf("%2d ", *p);
		
	}
	printf("\n\n");
	
	/*
	指向一維數(shù)組的指針變量
	*/ 
	int (*q)[4] = a;				//指針變量p指向4個整形元素的一維數(shù)組 
	for(int i = 0; i < 3; i++) {
		for(int j = 0; j < 4; j++) {
			printf("%2d ", *(*(q + i) + j));
		}
	}
	 
	return 0;
} 

用指向數(shù)組的指針做函數(shù)參數(shù)

#include<stdio.h>
//指向變量的指針變量
void avg(float *p, int n) {
	float sum = 0, ans = 0;
	float *p1 = p + 11;
	for(p; p <= p1; p++)
		sum = sum + *p;
	ans = sum / n;
	printf("%.2f\n", ans);
}
//指向一維數(shù)組的指針變量
void search(float (*p)[4], int n) {
	for(int i = 0; i < 4; i++) {
		printf("%.2f ", *(*(p + n) + i));
	}
}
int main() {
	float score[3][4] = {78, 90, 89, 34, 91, 61, 71, 84, 67, 76, 100, 53};
	avg(*score,12);	 
	search(score, 2);		 
	return 0;
}

指針指向 三維數(shù)組

在這里插入圖片描述

a[2][3][4]數(shù)組的結(jié)構(gòu):
兩個二維數(shù)組
三個一維數(shù)組
四個int類型的元素

首地址 指向 類型 移動一位 移動字節(jié)數(shù)
a a[0]這個二維數(shù)組 int(*)[3][4] a+1 48B
a[0] a[0][0]這個一維數(shù)組 int(*)[4] a[0]+1 16B
a[0][0] a[0][0][0]元素 int * a[0][0]+1 4B

指針指向 多維數(shù)組

原理與二維數(shù)組三維數(shù)組一樣
取元素的值:

在這里插入圖片描述

到此這篇關(guān)于C語言指針引用數(shù)組案例講解的文章就介紹到這了,更多相關(guān)C語言指針引用數(shù)組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解析ActiveMQ的使用說明總結(jié)

    解析ActiveMQ的使用說明總結(jié)

    本篇文章是對ActiveMQ的使用進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 淺談Windows系統(tǒng)下C語言編程中Glib庫的使用

    淺談Windows系統(tǒng)下C語言編程中Glib庫的使用

    這篇文章主要介紹了Windows系統(tǒng)下C語言編程中Glib庫的使用,Glib庫在多線程編程中經(jīng)??梢杂玫?需要的朋友可以參考下
    2016-02-02
  • 詳解C語言中的wait()函數(shù)和waitpid()函數(shù)

    詳解C語言中的wait()函數(shù)和waitpid()函數(shù)

    這篇文章主要介紹了C語言中的wait()函數(shù)和waitpid()函數(shù),注意其在中斷進程方面用法的不同,需要的朋友可以參考下
    2015-08-08
  • OpenCV實現(xiàn)馬賽克和毛玻璃濾鏡效果

    OpenCV實現(xiàn)馬賽克和毛玻璃濾鏡效果

    這篇文章主要為大家詳細介紹了OpenCV實現(xiàn)馬賽克和毛玻璃濾鏡效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++實現(xiàn)LeetCode(55.跳躍游戲)

    C++實現(xiàn)LeetCode(55.跳躍游戲)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(55.跳躍游戲),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • QT中QStringListModel類的應(yīng)用介紹

    QT中QStringListModel類的應(yīng)用介紹

    QStringListModel是最簡單的模型類,具備向視圖提供字符串數(shù)據(jù)的能力,本文主要介紹了QT中QStringListModel類的應(yīng)用介紹,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • C++ 異常處理 catch(...)介紹

    C++ 異常處理 catch(...)介紹

    catch(…)能夠捕獲多種數(shù)據(jù)類型的異常對象,所以它提供給程序員一種對異常 對象更好的控制手段,使開發(fā)的軟件系統(tǒng)有很好的可靠性
    2013-09-09
  • C++實現(xiàn)時間轉(zhuǎn)換及格式化

    C++實現(xiàn)時間轉(zhuǎn)換及格式化

    這篇文章主要為大家詳細介紹了C++中實現(xiàn)時間轉(zhuǎn)換及格式化的相關(guān)知識,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • 利用C語言實現(xiàn)掃雷游戲

    利用C語言實現(xiàn)掃雷游戲

    這篇文章主要為大家詳細介紹了利用C語言實現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • c++傳輸文件到不同計算機上的示例代碼

    c++傳輸文件到不同計算機上的示例代碼

    這篇文章主要為大家詳細介紹了c++傳輸文件到不同計算機上的相關(guān)知識,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03

最新評論