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

C語(yǔ)言中指針和數(shù)組試題詳解分析

 更新時(shí)間:2021年10月22日 09:42:08   作者:Dark And Grey  
變量存放在內(nèi)存中,內(nèi)存其實(shí)就是一組有序字節(jié)組成的數(shù)組,每個(gè)字節(jié)有唯一的內(nèi)存地址。CPU 通過(guò)內(nèi)存尋址對(duì)存儲(chǔ)在內(nèi)存中的某個(gè)指定數(shù)據(jù)對(duì)象的地址進(jìn)行定位。數(shù)據(jù)對(duì)象是指存儲(chǔ)在內(nèi)存中的一個(gè)指定數(shù)據(jù)類(lèi)型的數(shù)值或字符串,它們都有一個(gè)自己的地址,指針是保存這個(gè)地址的變量

指針 和 數(shù)組 試題解析 小編,在這里想說(shuō)一下,c語(yǔ)言的最后一節(jié) C預(yù)處理,可能還需要一些時(shí)間,因?yàn)樾【?,昨天才下載了虛擬機(jī) 和 linux 系統(tǒng),還沒(méi)開(kāi)始安裝。所以無(wú)法著手寫(xiě),因?yàn)?C預(yù)處理,vs2013很難表達(dá),也就意味可能會(huì)講不清楚。所以這篇文章可能需要點(diǎn)時(shí)間,再加上小編初期的文章,是沒(méi)有排版的(而且可能有些錯(cuò)誤,請(qǐng)大家以重置版為準(zhǔn)),所以這幾天我就把這些重新寫(xiě)。有興趣的朋友可以看看。(ps:如果哪一天沒(méi)有更新,意味著小編正在努力學(xué)習(xí),為了能給大家呈現(xiàn)一片詳細(xì)好懂的文章。)

下面直接進(jìn)入正文

數(shù)組題:

先給你們打個(gè)底

1. sizeof(數(shù)組名) ,此時(shí)的 數(shù)組名 代表的是 整個(gè)數(shù)組。

2. &數(shù)組名,此時(shí)的 數(shù)組名 代表的是 整個(gè)數(shù)組。

除了以上兩種特殊情況,其它的,幾乎 100% 代表的是首元素地址

另外有一點(diǎn)請(qǐng)記?。?arr[ i ] == *(arr + i ); arr[ i ][ j ] == *( *(arr + i)+ j)

好的,現(xiàn)在就讓我們進(jìn)入習(xí)題中,去磨練這份知識(shí),讓它再我們腦子里扎根

程序一(一維數(shù)組):

一維數(shù)組
#include<stdio.h>
int main()
{
	int a[] = {1,2,3,4};
	printf("%d\n", sizeof(a));// 16  計(jì)算的是整個(gè)數(shù)組的內(nèi)存大小
	// sizeof(數(shù)組名) 和 &數(shù)組名,此時(shí)數(shù)組名,代表的是整個(gè)數(shù)組 

	printf("%d\n", sizeof(a+0));// 輸出為 4 / 8 (地址所占大小只與多少位操作系統(tǒng)有關(guān),4byte【32位】,8byte【64】)
	// 因?yàn)?sizeof()的括號(hào)里放的不是數(shù)組名,而是 首元素地址 + 0,即sizeof(a[0])

	printf("%d\n", sizeof(*a));// 4  因?yàn)?a 沒(méi)有 &(取地址),沒(méi)有單獨(dú)放在sizeof()里(屬于非特殊情況,數(shù)組名代表首元素地址)
	// *a 就是首元素,這里求的是 首元素 的內(nèi)存大小,因?yàn)?這是一個(gè)整形數(shù)組,里面的每個(gè)元素都是 int 類(lèi)型,即為 4 byte

	printf("%d\n", sizeof(a+1));// 4 / 8  與a + 0 的意思是一樣的,只是現(xiàn)在這里跳過(guò)一個(gè)元素,也就是說(shuō)現(xiàn)在這是第二個(gè)元素的地址,地址的大小無(wú)非 就是 4/8 byte(受多少位系統(tǒng)影響,4byte【32位】,8byte【64位】)


	printf("%d\n", sizeof(a[1]));// 4  a[1] == *(a+1) 第二個(gè)元素的地址對(duì)齊解引用找到第二個(gè)元素,sizeof(a[1]),就是在求 第二個(gè)元素的大小,因?yàn)?這是一個(gè)整形數(shù)組,里面的每個(gè)元素都是 int 類(lèi)型,即為 4 byte

	printf("%d\n", sizeof(&a));// 4 / 8 &a 取出的是數(shù)組的地址,數(shù)組名沒(méi)有單獨(dú)放在sizeof括號(hào)里,而且 &a 取出的是整個(gè)數(shù)組的地址,sizeof(&a) 就是在愛(ài)求 數(shù)組的地址大小
	//  數(shù)組的地址也是地址 ,也受多少位操作系統(tǒng)影響: 4 byte【32位】 / 8byte 【64位】

	printf("%d\n", sizeof(*&a));// 16  &a 取出的是數(shù)組的地址,對(duì)取其解引用,找到數(shù)組名a,也就是說(shuō) * 和 & 相互抵消了,等于就是說(shuō) sizeof(數(shù)組名) ,此時(shí)數(shù)組名代表的是整個(gè)數(shù)組

	printf("%d\n", sizeof(&a+1));// 4 / 8  &a,拿出的是數(shù)組a的地址,+1跳過(guò)整個(gè)數(shù)組,但還是一個(gè)地址,受多少位操作系統(tǒng)影響: 4 byte【32位】 / 8byte 【64位】

	printf("%d\n", sizeof(&a[0]));// 4 / 8  [] 的優(yōu)先級(jí) 比 & 高,a 先和 [] 結(jié)合形成一個(gè)數(shù)組,在對(duì)其取地址,又因?yàn)?a[0] == *(a+0),即這里 &a[0],取出的是 首元素的地址,既然是地址,就要受多少位操作系統(tǒng)影響: 4 byte【32位】 / 8byte 【64位】

	printf("%d\n", sizeof(&a[0]+1));// 4 / 8    [] 的優(yōu)先級(jí) 比 & 高,a 先和 [] 結(jié)合形成一個(gè)數(shù)組,在對(duì)其取地址,又因?yàn)?a[0] == *(a+0),即這里 &a[0],取出的是 首元素的地址,此時(shí)加一,跳過(guò)一個(gè)整形,也就是說(shuō) 此時(shí)的地址 是 第二個(gè)元素的地址,既然是地址,就要受多少位操作系統(tǒng)影響: 4 byte【32位】 / 8byte 【64位】

	return 0; 
}

字符數(shù)組

1. sizeof(數(shù)組名) ,此時(shí)的 數(shù)組名 代表的是 整個(gè)數(shù)組。

2. &數(shù)組名,此時(shí)的 數(shù)組名 代表的是 整個(gè)數(shù)組。

除了以上兩種特殊情況,其它的,幾乎 100% 代表的是首元素地址

另外有一點(diǎn)請(qǐng)記住: arr[ i ] == *(arr + i );

arr[ i ][ j ] == *( *(arr + i)+ j)

程序二(字符數(shù)組):

#include<stdio.h>
int main()
{
	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	printf("%d\n",sizeof(arr));// 6  arr是一個(gè)字符數(shù)組,每一個(gè)元素的內(nèi)存大小為 1 byte,該數(shù)組有 5個(gè) 元素,即 6 byte
	
	printf("%d\n", sizeof(arr+0));//4 / 8  arr+0 == 首元素地址,既然是地址,就要受多少位操作系統(tǒng)影響: 4 byte【32位】 / 8byte 【64位】

	printf("%d\n", sizeof(*arr));// 1   *arr(對(duì)首元素地址進(jìn)行解引用) == 首元素,此時(shí)計(jì)算的是首元素的大小,即 1 byte
	
	printf("%d\n", sizeof(arr[1]));// 1   arr[1] == *(arr+1),即第二個(gè)元素,即 sizeof 計(jì)算的是一個(gè)元素的大小,即 1 byte
	
	printf("%d\n", sizeof(&arr));// 4 / 6  &arr  取出的是 數(shù)組的地址,既然是地址,就要受多少位操作系統(tǒng)影響: 4 byte【32位】 / 8byte 【64位】
	
	printf("%d\n", sizeof(&arr+1));// 4 / 8 &arr  取出的是數(shù)組的地址,在對(duì)其 加一,即跳過(guò)整個(gè)數(shù)組,此時(shí)地址是數(shù)組中不包含的地址,越界了,假設(shè)  數(shù)組有 5 個(gè)元素,下標(biāo)0 ~ 4,此時(shí)的地址是 下標(biāo)為 5 的地址,有人肯能會(huì)有,那這個(gè)不應(yīng)該是錯(cuò)的嗎》怎么還有大小?,
	//因?yàn)?sizeof 是不會(huì)真的去訪(fǎng)問(wèn)越界的位置,只是看看那個(gè)位置的數(shù)據(jù)是什么類(lèi)型,并不涉及訪(fǎng)問(wèn)和計(jì)算。
	//因?yàn)槭堑诹鶄€(gè)元素的地址,既然是地址,就要受多少位操作系統(tǒng)影響: 4 byte【32位】 / 8byte 【64位】
	
	printf("%d\n", sizeof(&arr[0]+1));// 4 / 8  這個(gè)就不用我多說(shuō)了,它就就是一個(gè)地址,第二個(gè)元素的地址(&arr[0] + 1 == 首元素地址 + 1,即首元素地址 挑過(guò)一個(gè) 字節(jié),),既然是地址,就要受多少位操作系統(tǒng)影響: 4 byte【32位】 / 8byte 【64位】
	
	return 0; 
}

接下我們把 sizeof 換成 strlen ,來(lái)看看這些題會(huì)發(fā)生什么變化? 在開(kāi)始之前請(qǐng)注意一下內(nèi)容: 1. strlen 只有 遇到 ‘\0',才會(huì)停止計(jì)數(shù)。計(jì)數(shù)個(gè)數(shù)(不包括 ‘\0' 這個(gè)元素),如果沒(méi)有 ‘\0',strlen 這個(gè)函數(shù)就會(huì)往后面找 ‘\0',所以 strlen 的返回值,在沒(méi)有 '\0'的情況下,返回 一個(gè)隨機(jī)值。 2.strlen(這里要放一個(gè)地址),如果不是,會(huì)導(dǎo)致程序崩潰 舉個(gè)列子:strlen(a),a 的 地址為 97,strlen 就會(huì) 以 97 為地址,開(kāi)始往后 一邊尋找 ‘\0',一邊計(jì)數(shù),很容易形成越界訪(fǎng)問(wèn),從而導(dǎo)致程序崩潰

程序三(字符數(shù)組):

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	printf("%d\n", strlen(arr));//  隨機(jī)值, 沒(méi)有'\0'·從首元素開(kāi)始計(jì)數(shù),且向后尋找'\0',但是該數(shù)組里沒(méi)有'\0'的,所以它會(huì)一直往后找'\0',直到找到了才停止計(jì)數(shù),所以返回的是一個(gè)隨機(jī)值
	
	printf("%d\n", strlen(arr + 0));// 隨機(jī)值,還是從首元素開(kāi)始計(jì)數(shù),且向后尋找'\0',但是該數(shù)組里沒(méi)有'\0'的,所以它會(huì)一直往后找'\0',直到找到了才停止計(jì)數(shù),所以返回的是一個(gè)隨機(jī)值
	
	//printf("%d\n", strlen(*arr));// *arr == 'a' == 97 strlen(把97當(dāng)成一個(gè)地址),非法訪(fǎng)問(wèn),程序崩潰
	
	//printf("%d\n", strlen(arr[1]));// 與上表達(dá)式一樣, 非法訪(fǎng)問(wèn),程序崩潰
	
	printf("%d\n", strlen(&arr));//  隨機(jī)值
	printf("%d\n", strlen(&arr + 1));//  隨機(jī)值 - 6 ,與上表示式的隨機(jī)值 ,相差 6,因?yàn)?&arr 讀取的是數(shù)組的地址,加一 等于 跳過(guò)一個(gè)個(gè)數(shù)組,也就是跳過(guò)了 6 個(gè)元素,也就是說(shuō)這六個(gè)元素,沒(méi)有被計(jì)入,現(xiàn)在是 第 7 個(gè)元素的地址,從第七個(gè)元素開(kāi)始 計(jì)數(shù) 和 尋找 '\0'
	
	printf("%d\n", strlen(&arr[0] + 1));// 隨機(jī)值 - 1,與 上上 表達(dá)式的隨機(jī)值,相差 1,這里是從 第二個(gè)元素,開(kāi)始 計(jì)數(shù) 與 尋找'\0',第一個(gè)元素沒(méi)有計(jì)入在內(nèi)
	
	return 0;
}

程序四(字符數(shù)組):

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "abcdef";//  ==  "abcdef" == 'a', 'b', 'c', 'd', 'e', 'f', '\0'
	printf("%d\n", sizeof(arr));// 7  后面隱藏一個(gè)元素 '\0'
	
	printf("%d\n", sizeof(arr + 0));// 4 / 8 是一個(gè)地址,
	printf("%d\n", sizeof(*arr));//  1   *arr == 首元素,這里計(jì)算的是首元素的內(nèi)存大小
	printf("%d\n", sizeof(arr[1]));// 1  計(jì)算第二個(gè)元素的內(nèi)存大小
	printf("%d\n", sizeof(&arr));// 4 / 8  ,這是一個(gè)地址
	printf("%d\n", sizeof(&arr + 1));// 4 / 8 ,這是一個(gè)地址
	printf("%d\n", sizeof(&arr[0]) + 1);// 4 / 8, 這是一個(gè)地址



	printf("%d\n", strlen(arr));//   6   遇到'\0'停止計(jì)數(shù),'\0'不計(jì)入在內(nèi)
	printf("%d\n", strlen(arr + 0));//  6  arr+0 == arr 從首元素開(kāi)始計(jì)數(shù),遇到'\0'停止計(jì)數(shù),'\0'不計(jì)入在內(nèi)
	printf("%d\n", strlen(*arr));//   *arr  ==  a == 97,以97為地址( 從 97 開(kāi)始計(jì)算直到遇到'\0' ),屬于非法訪(fǎng)問(wèn),程序崩潰
	printf("%d\n", strlen(arr[1]));//  arr[1]  ==  b == 98,以98為地址( 從 98 開(kāi)始計(jì)算直到遇到'\0' ),屬于非法訪(fǎng)問(wèn),程序崩潰
	printf("%d\n", strlen(&arr));//  6  &arr 雖然是數(shù)組的地址,但是對(duì)于strlen函數(shù)來(lái)說(shuō),它就只是第一個(gè)元素的地址,從該元素開(kāi)始計(jì)數(shù),遇到'\0'停止計(jì)數(shù),'\0'不計(jì)入在內(nèi)
	printf("%d\n", strlen(&arr + 1));// 隨機(jī)值,跳過(guò)了一個(gè)數(shù)組,從 '\0' 后面 開(kāi)始計(jì)數(shù),直到遇到'\0'停止計(jì)數(shù),'\0'不計(jì)入在內(nèi)
	printf("%d\n", strlen(&arr[0]) + 1);// 5 從第二個(gè)元素開(kāi)始計(jì)數(shù),遇到'\0'停止計(jì)數(shù),'\0'不計(jì)入在內(nèi)

	return 0;
}

程序五(字符數(shù)組):

#include<stdio.h>
#include<string.h>
int main()
{
	char* p = "abcdef";// p 存的是 字符串的首元素的a的地址
	printf("%d\n", sizeof(p));// 4  / 8    a 的地址
	printf("%d\n", sizeof(p + 0));// 4 / 8 b 的地址,
	printf("%d\n", sizeof(*p));//  1   *arr == 首元素 a,這里計(jì)算的是首元素的內(nèi)存大小
	printf("%d\n", sizeof(p[0]));// 1  計(jì)算第一個(gè)元素的內(nèi)存大小 p[0] == *(p+0) == a
	printf("%d\n", sizeof(&p));//  4 / 8  把指針變量本身的地址取出來(lái)了,是一個(gè)地址
	printf("%d\n", sizeof(&p + 1));// 4 / 8   取出 指針變量 p的 地址,加上 1,是誰(shuí)的地址,不知道也不重要,因?yàn)樗€是一個(gè)地址
	printf("%d\n", sizeof(&p[0] + 1));// 4 / 8, &(*(p+0)) +1 ,a的地址加上一字節(jié),改地址是 b 的地址



	printf("%d\n", strlen(p));//  6  指針變量 p 存的是 a的地址,從a開(kāi)始計(jì)算,直到遇到'\0'停止,'\0'不計(jì)入在內(nèi)
	printf("%d\n", strlen(p + 1));// 5  指針變量 p 存的是 b 的地址,從b開(kāi)始計(jì)算,直到遇到'\0'停止,'\0'不計(jì)入在內(nèi)
	printf("%d\n", strlen(*p));//  *p == a == 97,以97為地址( 從 97 開(kāi)始計(jì)算直到遇到'\0' ),屬于非法訪(fǎng)問(wèn),程序崩潰
	printf("%d\n", strlen(p[0]));//  p[0] == a == 97,以97為地址( 從 97 開(kāi)始計(jì)算直到遇到'\0' ),屬于非法訪(fǎng)問(wèn),程序崩潰
	printf("%d\n", strlen(&p));// 隨機(jī)值, 這里是指針變量 p 的地址,不是a的地址,而 p 后面什么時(shí)候能遇到 '\0',我們不知道,所以返回一個(gè) 隨機(jī)值
	printf("%d\n", strlen(&p + 1));// 隨機(jī)值,這里還是取的 指針變量 p 的地址,對(duì)齊加一,跳過(guò)一個(gè)p,意味著 strlen 少計(jì)數(shù) 一整個(gè) p 所含的元素
	printf("%d\n", strlen(&p[0] + 1));//  5  取出第一個(gè)元素的地址加一,到第 二 個(gè)元素,從第二個(gè)元素計(jì)算,直到遇到'\0'停止,'\0'不計(jì)入在內(nèi)

	return 0;
}

二維數(shù)組

1. sizeof(數(shù)組名) ,此時(shí)的 數(shù)組名 代表的是 整個(gè)數(shù)組。

2. &數(shù)組名,此時(shí)的 數(shù)組名 代表的是 整個(gè)數(shù)組。

除了以上兩種特殊情況,其它的,幾乎 100% 代表的是首元素地址

另外有一點(diǎn)請(qǐng)記?。?arr[ i ] == *(arr + i );

arr[ i ][ j ] == *( *(arr + i)+ j)

arr[ i ][ j ] ,arr[ i ] 就是一維數(shù)組的數(shù)組名

在這里插入圖片描述

程序六( 二維數(shù)組):

#include<stdio.h>
#include<string.h>
int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//  48   此時(shí) 數(shù)組名 a 代表的是整個(gè)數(shù)組,意味著 sizeof 計(jì)算的是整個(gè)數(shù)組的大小; 3*4*4 = 12*4 = 48
	printf("%d\n", sizeof(a[0][0]));// 4  第一行第一個(gè)元素
	printf("%d\n", sizeof(a[0]));//  16 把第0行看成一個(gè)一維數(shù)組,a[0]就是一個(gè)一維數(shù)組的數(shù)組名,所以計(jì)算的整個(gè)第 0 行元素的內(nèi)存大小 4 * 4 = 16
	printf("%d\n", sizeof(a[0] + 1));//  4 / 8   第0行 第2個(gè)元素的地址
	printf("%d\n", sizeof(*(a[0] + 1)));//  4    第0行 第2個(gè)元素  a[0][1] == *(*(a+0)+1)

	printf("%d\n", sizeof(a + 1));// 4  / 8     第1行 的 一維數(shù)組 的 地址,*(a +1) = arr[1],不就是第1行 一維數(shù)組的 數(shù)組名,在對(duì)其 &(取地址),既然是一個(gè)地址,就要受多少位操作系統(tǒng)影響: 4 byte【32位】 / 8byte 【64位】
	
	printf("%d\n", sizeof(*(a + 1)));// 16   解引用 第一行的一維數(shù)組的數(shù)組名(首元素)的地址,等于就是找到第一行的一維數(shù)組的數(shù)組名,
	                                 //sizeof(第一行 的 數(shù)組名 ),所以計(jì)算的是整個(gè)第一行元素的內(nèi)存大小

	printf("%d\n", sizeof(&a[0] + 1));//  4 / 8   第 1 行(第一行的一維數(shù)組名)的 地址,
	printf("%d\n", sizeof(*(&a[0]) + 1));// 16 解引用 第 1 行(第一行的一維數(shù)組名)的 地址,等于找到了 第 1 行的一維數(shù)組的數(shù)組名
	                                     //sizeof(第一行 的 數(shù)組名 ),所以計(jì)算的是整個(gè)第一行元素的內(nèi)存大小
	printf("%d\n", sizeof(*a));// 16  a是首元素的地址(第 0 行的數(shù)組地址) ,*a(解引用 a )找到了第0行數(shù)組名,
	                           //計(jì)算的是整個(gè)第 0 行所有元素的內(nèi)存大小
	printf("%d\n", sizeof(a[3]));//16  ,另外  sizeof()括號(hào)里表達(dá)式不會(huì)計(jì)算,也就是說(shuō)不會(huì)真的訪(fǎng)問(wèn)第四行數(shù)據(jù),它只是把第四行的數(shù)組名放在這里()
	                             //意思這里有第四行,就意味著 第四行 有 它自己 的 類(lèi)型  ,其實(shí)這里  a[3] 跟 a[0] 一樣的道理,
	                             //a[3] 是第四行的數(shù)組名,那有 第四行嗎?其實(shí)沒(méi)有,但并不妨礙,因?yàn)槲覀儾蝗ピL(fǎng)問(wèn) 
	                             // 而且 sizeof() 括號(hào)里的 表達(dá)式 是不參與真實(shí)運(yùn)算的 ,只是 根據(jù) 它的類(lèi)型 計(jì)算 它的大小
	                            // 所以 a[3] 是一個(gè)一維數(shù)組,而且有 4 個(gè)整形的一維數(shù)組,sizeof(a[3]) == 4 * 4 == 16

	return 0;
}

指針題

在這里插入圖片描述

程序七( 指針):

#include<stdio.h>
int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int* ptr = (int*)(&a + 1);// 數(shù)組的指針類(lèi)型,不能放進(jìn)一個(gè)整形指針里,所以這里強(qiáng)制類(lèi)型轉(zhuǎn)換,但值沒(méi)有發(fā)生變換,
	                         // 存的值,還是跳過(guò)一個(gè)數(shù)組的指向的那個(gè)值(未知量)
	printf("%d,%d\n", *(a + 1), *(ptr - 1));// 整形指針 ptr 減一,指向 5 的 那個(gè)位置,再解引用就是5
	return 0;         //  2         5
}

程序八( 指針):

include<stdio.h>
struct test
{
	int num;
	char* pcname;
	short s_date;
	char cha[2];
	short s_ba[4];
}* p;

 假設(shè) p 的 值為  0x10 00 00 00,如下表達(dá)式分別為多少
 已知結(jié)構(gòu)體 test 類(lèi)型 的 變量 大小為 20個(gè)字節(jié)
#include<stdio.h>
int main()
{
	p = (struct test*)0x100000;
	printf("%p\n", p + 0x1);// 0x1 == 1 這里加1 等于跳過(guò)了一個(gè)結(jié)構(gòu)體(20字節(jié))
	//0x10 00 00 + 20 ==0x10 00 14  因?yàn)?%p(32位)
	//打印  0x 00 10 00 14

	printf("%p\n", (unsigned long)p + 0x1); // 強(qiáng)制類(lèi)型轉(zhuǎn)換 無(wú)符號(hào)長(zhǎng)整形類(lèi)型,0x100000 轉(zhuǎn)換為 10 進(jìn)制 -> 1048576 + 1 = 1048577 -> 0x10 00 01
	     // %p, 即0x 00 10 00 01

	printf("%p\n", (unsigned int*)p + 0x1);//強(qiáng)制類(lèi)型轉(zhuǎn)換 無(wú)符號(hào)整形指針類(lèi)型 加1 == 就是跳過(guò)一個(gè)無(wú)符號(hào)整形 指針(4 byte)
	// 即 0x 00 10 00 04
	return 0;   
}

程序九( 指針):

在這里插入圖片描述

#include<stdio.h>
int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int* ptr1 = (int*)(&a + 1);
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);// %x 十六進(jìn)制數(shù)
	return 0;     //   4      2 000 000
}  
//       1                 2                    3                   4
//  01 00 00 00        02 00 00 00         03 00 00 00         04 00 00 00
// 低地址                                                         高地址(小端 存儲(chǔ):低字節(jié)存低地址,高字節(jié)存高地址)
// a 是數(shù)組名(首元素地址),指向 1 所在的地址(01前面)。這時(shí)類(lèi)型強(qiáng)制轉(zhuǎn)換 整形,加1(1字節(jié)),
// 再將他轉(zhuǎn)換為一個(gè)地址,在對(duì)其解引用 ,此時(shí)它(ptr2)指向 01 的后面,又因?yàn)閜tr2是int 類(lèi)型
//也就是說(shuō)它一次訪(fǎng)問(wèn) 4 個(gè)字節(jié)的內(nèi)容( 00 00 00 02 ) 取出來(lái)使反著讀?。◤母呶婚_(kāi)始讀取),02 00 00 00 
// 按十六進(jìn)制 輸出 (0x 02 00 00 00) 即,2 000 000

程序十( 指針):

#include<stdio.h>
int main()
{                  //    1       3         5
	int a[3][2] = { ( 0, 1 ), ( 2, 3 ), ( 4, 5) };// a 是一個(gè) 3排 2列 的 二維數(shù)組
	int* p;         //逗號(hào)表達(dá)式,以最后一個(gè)表達(dá)式結(jié)果為準(zhǔn)
	               //  數(shù)組存儲(chǔ)情況      1 3
	               //                   5 0
	               //                   0 0
	p = a[0];
	printf("%d\n",p[0]); //  1
	return 0;
}

程序十( 圖):

在這里插入圖片描述

#include<stdio.h>
int main()
{
	int a[5][5];
	//    a[0]        a[1]         a[2]         a[3]           a[4]
	// 口口口口口  口口口口口   口口口口口   口口口口口     口口口口口
	// |      |         |         |         |   |         |
	//p[0]   p[1]      p[2]       p[3]     p[4] |       a[4][2]
	//                                       p[4][2]
 	int(*p)[4]; 
	p = a;//  p的類(lèi)型 int(*)[4]    a的類(lèi)型 int(*)[5]
	// p 是一個(gè)指向整形數(shù)組的指針,有4個(gè)元素
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);// a 先和 [] 集合([]的優(yōu)先級(jí)高)
	return 0;      //  p[4] == *(p+4)   p[4][2] == *(*(p + 4) + 2)
	              // 指針減指針 等于兩個(gè)指針之間的元素個(gè)數(shù) ,&p[4][2] - &a[4][2]  ==  - 4
} 
 打印的條件  :%d == - 4
 -4  1000 0000 0000 0000 0000 0000 0000 0100 原碼(打?。?
 1111 1111 1111 1111 1111 1111 1111 1100  補(bǔ)碼(存儲(chǔ))
 
 %p 認(rèn)為內(nèi)存上放的是地址,地址就沒(méi)有原反補(bǔ)碼的概念(無(wú)符號(hào)數(shù)) 
 整形在內(nèi)存中,以補(bǔ)碼類(lèi)型存儲(chǔ),所以直接以補(bǔ)碼當(dāng)做地址輸出
     1111 1111 1111 1111 1111 1111 1111 1100 原碼符號(hào)位不變,其余位按位取反,再加 1
 0x    f    f   f     f    f   f    f   c
 所以%p 的輸出結(jié)果是 ffff fffc

程序十一( 指針):

#include<stdio.h>
int main()
{
	int a[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* ptr1 = (int*)(&a + 1);//跳過(guò)整個(gè)二維數(shù)組
	int* ptr2 = (int*)(*(a + 1));// 第一行的數(shù)組名
	// int aa[5]={0};
	// int* p = arr;
	// *(aa+2) == a[2] == *(p + 2) 
	printf("%d,%d\n",*(ptr1 - 1),*(ptr2 - 1));
	return 0;//           10            5
}

程序十二( 指針):

#include<stdio.h>
int main()
{
	char* a[] = { "work", "at", "alibaba" };// char *p = "abcdef"; p 存的是字符串首元素(a)的地址
	  //這里也是一樣,字符指針數(shù)組 a ,數(shù)組名 a == 首元素("work")中 'w ' 的地址
	char* *pa = a;// *pa(指針),類(lèi)型 char* ,*pa指向第一個(gè)元素(a == 首元素的地址)
    //  遺跡指針的地址需要一個(gè)二級(jí)指針來(lái)接收
    
	pa++;//跳過(guò)一個(gè)char*,指向第二個(gè)元素,
	printf("%s\n",*pa);// at
	return 0;
}

程序十三( 指針):

#include<stdio.h>
int main()
{
	char*c[] = { "ENTER", "NEW", "POINT", "FIRST" };
	char* *cp[] = { c + 3, c + 2, c + 1, c };
	           // FIRST   POINT   NEW   ENTER

	// c[]                       cp
	// char*   ENTER          c+3  char**   FIRST  -> cpp
	// char*   NEW            c+2  char**   POINT
	// char*   POINT          c+1  char**   NEW 
	// char*   FIRST           c   char**   ENTER

	char** *cpp = cp;
	printf("%s\n",* *++cpp); // POINT   此時(shí)cpp指向第二個(gè)元素(c+2),再對(duì)其解引用  POINT 的首元素地址

       此時(shí) cpp 指向 c+2(第二個(gè)元素) 處,因?yàn)?上面 ++cpp  改變 cpp 的指向
	printf("%s\n", *--*++cpp + 3); // ER  ++  -- 優(yōu)先級(jí)比 + 高,
	//所以先加加,此時(shí)cpp指向第三個(gè)元素,再進(jìn)行 *(解引用)== 第三個(gè)元素(c+1),
	//再 -- (第三個(gè)元素減一),即 c + 1 - 1 == c ,再進(jìn)行 *(解引用),此時(shí) 等于  ENTER (此時(shí)類(lèi)似于數(shù)組名)
	// 最后再加 3 (ENTER + 3),最終指向 "ENTER"中第四個(gè)元素 E 的地址  ,然后從 E 開(kāi)始往后打印,直到遇到'\0'停止,
	// 即 最后輸出為 :  ER
	
注意此時(shí)的 char**cp[]={c+3,c+2,c,c};因?yàn)?在 *++p,解引用找到第三個(gè)元素 c+1之后,前置減減了一波。所以改變了 第三個(gè)元素的值
      

	// 另外 注意 此時(shí) cpp是指向第三個(gè)元素 c 的。
	printf("%s\n", *cpp[-2] + 3); // *cpp[-2] + 3 = *(cpp-2) + 3  ; cpp-2 == cpp[0] ==(c+3)
	                              // 再對(duì)其解引用,等于 FIRST
	                              // 再加上三,此時(shí)指向(FIRST 此時(shí)類(lèi)似于數(shù)組名),F(xiàn)IRST + 3 第四個(gè)元素 S 的地址
	                              // 然后從 S 開(kāi)始打印,直到遇到'\0'停止。
	                              //  即 最后輸出為:ST

	// 注意 此時(shí) cpp 還是指向第三個(gè)元素 c 的(前面 *cpp[-2],并不會(huì)改變其值,它只是加上一個(gè)數(shù),然后去訪(fǎng)問(wèn),就好比 一個(gè)人 站著凳子 去拿柜子上高處的東西,并不會(huì)改變自身身高,而前置和后置 ++,自增,也就是說(shuō)等自己長(zhǎng)高了再去拿,此時(shí)的身高已經(jīng)改變了),
	printf("%s\n", cpp[-1][-1] + 1);
	           // ==  *( *(cpp - 1) -1 ) + 1
	           //  *(cpp - 1) == c + 2
	          // 再 減 1, c + 2 - 1 = c + 1
	          // 在對(duì)其解引用 等于 NEW
	          // 再加 1 ,NEW(此時(shí)類(lèi)似于數(shù)組名) +1 ,此時(shí)得到了第二個(gè)元素(E)的地址
	          //然后 從  E 這里開(kāi)始打印,直到遇到'\0'停止。
	          // 即 最后輸出為 EW

	return 0;
}

如果有疑問(wèn),歡迎在下面評(píng)論。本文至此就全部結(jié)束了。

到此這篇關(guān)于C語(yǔ)言中指針和數(shù)組試題詳解分析的文章就介紹到這了,更多相關(guān)C語(yǔ)言 指針和數(shù)組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解次小生成樹(shù)以及相關(guān)的C++求解方法

    詳解次小生成樹(shù)以及相關(guān)的C++求解方法

    這篇文章主要介紹了詳解次小生成樹(shù)以及相關(guān)的C++求解方法,文中的練習(xí)示例采用了kruskal算法通過(guò)C++進(jìn)行求解,需要的朋友可以參考下
    2015-08-08
  • C語(yǔ)言中聯(lián)合體與共用體和枚舉使用語(yǔ)法示例

    C語(yǔ)言中聯(lián)合體與共用體和枚舉使用語(yǔ)法示例

    這篇文章主要介紹了C語(yǔ)言中聯(lián)合體與共用體和枚舉使用語(yǔ)法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-12-12
  • C++獲取內(nèi)存使用情況小結(jié)

    C++獲取內(nèi)存使用情況小結(jié)

    在程序編程過(guò)程中,為了防止出現(xiàn)內(nèi)存泄漏情況出現(xiàn),需要持續(xù)關(guān)注內(nèi)存程序內(nèi)存占用情況,本文主要介紹了C++獲取內(nèi)存使用情況小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • C語(yǔ)言實(shí)現(xiàn)控制臺(tái)五子棋小游戲

    C語(yǔ)言實(shí)現(xiàn)控制臺(tái)五子棋小游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)控制臺(tái)五子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 解決gcc編譯報(bào)錯(cuò)unknown type name ‘bool‘問(wèn)題

    解決gcc編譯報(bào)錯(cuò)unknown type name ‘bool‘問(wèn)題

    這篇文章主要介紹了解決gcc編譯報(bào)錯(cuò)unknown type name ‘bool‘問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • C 語(yǔ)言基礎(chǔ)教程(我的C之旅開(kāi)始了)[六]

    C 語(yǔ)言基礎(chǔ)教程(我的C之旅開(kāi)始了)[六]

    C 語(yǔ)言基礎(chǔ)教程(我的C之旅開(kāi)始了)[六]...
    2007-02-02
  • C/C++如何實(shí)現(xiàn)兩矩陣相乘之模擬法

    C/C++如何實(shí)現(xiàn)兩矩陣相乘之模擬法

    C++矩陣運(yùn)算矩陣運(yùn)算包括矩陣相加、相減、相乘、轉(zhuǎn)置、求逆矩陣等等,用計(jì)算機(jī)程序?qū)崿F(xiàn)矩陣運(yùn)算的方法算法很多,這篇文章主要給大家介紹了關(guān)于C/C++如何實(shí)現(xiàn)兩矩陣相乘之模擬法的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • C++游戲教程基本技巧之隨機(jī)化詳解

    C++游戲教程基本技巧之隨機(jī)化詳解

    在小游戲的制作中時(shí)常常會(huì)要用到隨機(jī)數(shù),這篇文章就來(lái)和大家談?wù)凜++中這個(gè)所謂的“隨機(jī)”。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-11-11
  • VC中CDC、HDC、pDC區(qū)別與聯(lián)系及相互轉(zhuǎn)換

    VC中CDC、HDC、pDC區(qū)別與聯(lián)系及相互轉(zhuǎn)換

    這篇文章主要介紹了VC中CDC、HDC、pDC區(qū)別與聯(lián)系及相互轉(zhuǎn)換的方法,非常的詳細(xì),有需要的小伙伴可以參考下,希望對(duì)大家學(xué)習(xí)VC能夠有所幫助。
    2015-11-11
  • C語(yǔ)言 函數(shù)缺省參數(shù)詳情

    C語(yǔ)言 函數(shù)缺省參數(shù)詳情

    這篇文章主要介紹了C語(yǔ)言 的函數(shù)缺省參數(shù)、除了介紹函數(shù)全缺省參數(shù),和半缺省參數(shù)還簡(jiǎn)單介紹了函數(shù)聲明、函數(shù)調(diào)用等一些函數(shù)的定義,需要的朋友可以參考下面文章內(nèi)容
    2021-09-09

最新評(píng)論