前言:
前面我們剛剛學完了C語言:指針詳解【進階】的知識,這部分的知識還是要重在理解加實踐,今天我這里就分享一些有關C語言指針方面的練習供大家更深入的理解指針的知識。
我們初期的指針學習大部分都是與數(shù)組的知識綁定在一起的,所以今天的練習也是大多與數(shù)組有關的,目的是透過數(shù)組中指針的操作幫助強化理解指針在內(nèi)存中的是如何操作的。
話不多說,直接上題:
一維數(shù)組
關于數(shù)組對于sizeof()和strlen函數(shù)的使用,這里先回顧一下:
數(shù)組名大部分情況下代表數(shù)組的首元素的地址
有兩種情況例外:
- 數(shù)組名單獨放在sizeof內(nèi)部,這里數(shù)組名代表整個數(shù)組,計算的是整個數(shù)組的大小
- &數(shù)組名,這里取出的是整個數(shù)組的地址
sizeof()計算的是數(shù)據(jù)在內(nèi)存中所占的字節(jié)大小
strlen函數(shù)只能計算字符串的長度,計算過程中遇到\0
結束
關于strlen函數(shù)和sizeof()的練習
下面程序輸出結果是什么?
整型數(shù)組
練習一:
#include <stdio.h>
int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a + 0));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(a[1]));
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(*&a));
printf("%d\n", sizeof(&a + 1));
printf("%d\n", sizeof(&a[0]));
printf("%d\n", sizeof(&a[0] + 1));
return 0;
}
結果:
分析:
內(nèi)存:
對應題查看對應顏色的解釋哦。
字符數(shù)組
練習二:
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
return 0;
}
這里分兩部分練習(sizeof的為一部分,strlen的為一部分)
sizeof的結果:
分析:
內(nèi)存:
strlen的結果:
注意:strlen函數(shù)的參數(shù)類型
分析:
練習三:
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
return 0;
}
注意這里的字符數(shù)組在內(nèi)存中的存儲形式
這里分兩部分練習(sizeof的為一部分,strlen的為一部分)
sizeof的結果:
分析:
內(nèi)存:注意這個數(shù)組后面還放了'\0','\0'也要占一個字節(jié)
strlen的結果:
注意:strlen函數(shù)的參數(shù)類型
分析:
指針
練習三:
#include <stdio.h>
#include <string.h>
int main()
{
char* p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p + 1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p + 1));
printf("%d\n", sizeof(&p[0] + 1));
printf("%d\n", strlen(p));
printf("%d\n", strlen(p + 1));
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p + 1));
printf("%d\n", strlen(&p[0] + 1));
return 0;
}
這里分兩部分練習(sizeof的為一部分,strlen的為一部分)
sizeof的結果:
分析:
內(nèi)存:
strlen的結果:
注意:strlen函數(shù)的參數(shù)類型
分析:
練習三:
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
return 0;
}
注意這里的字符串在內(nèi)存中的存儲形式
這里分兩部分練習(sizeof的為一部分,strlen的為一部分)
sizeof的結果:
分析:
內(nèi)存:注意這個字符串后面還放了'\0','\0'也要占一個字節(jié)
strlen的結果:
注意:strlen函數(shù)的參數(shù)類型
分析:
傳入的是二級指針時指向的就是指針p的地址,strlen計算的就是從p的地址開始向后計算遇到
\0
時的長度。
二維數(shù)組
練習四:
#include <stdio.h>
int main()
{
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a[0][0]));
printf("%d\n", sizeof(a[0]));
printf("%d\n", sizeof(a[0] + 1));
printf("%d\n", sizeof(*(a[0] + 1)));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(*(a + 1)));
printf("%d\n", sizeof(&a[0] + 1));
printf("%d\n", sizeof(*(&a[0] + 1)));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a[3]));
return 0;
}
結果:
分析:
該二維數(shù)組在內(nèi)存中是三個一維數(shù)組連續(xù)存放的。
內(nèi)存:
筆試題
通過上面的練習,相信你應該已經(jīng)能理解指針在內(nèi)存中的操作了,下面是幾道筆試題,一起來檢驗一下學習成果吧。
筆試題1:
#include <stdio.h>
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int* ptr = (int*)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
//程序的結果是什么?
結果:
分析:
筆試題2:
//由于還沒深入學習結構體,這里告知結構體Test類型的大小是20個字節(jié)
struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
#include <stdio.h>
int main()
{
p = 0x100000;
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
結果:
分析:
筆試題3:
#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);
return 0;
}
結果:
分析:
%x
:打印16進制的數(shù)字
注意:這里需要畫更細致的內(nèi)存分布圖才能分析清指針的操作
(默認小端存儲)
筆試題4:
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int* p;
p = a[0];
printf("%d", p[0]);
return 0;
}
結果:
分析:
這道題其實考的是大家對操作符的了解,對于一個二維數(shù)組來說,要在二維數(shù)組內(nèi)初始化,需要用到的是{}
,而不是()
,這里的()
是逗號表達式的操作符。
( , , )
:逗號表達式是以此執(zhí)行括號內(nèi)的語句,但只有最后一句的表達式是整個逗號表達式的值。
所以,這里的二維數(shù)組中只初始化了前三個元素1,2,3
,后面的元素都為0
,a[0]
代表第一行的地址,p[0]
就是第一行第一個元素1
。
筆試題5:
#include <stdio.h>
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
結果:
分析:
這里要注意不同類型的指針一次能訪問到的空間是不同的
注意:地址是16進制數(shù)字
筆試題6:
#include <stdio.h>
int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr1 = (int*)(&aa + 1);
int* ptr2 = (int*)(*(aa + 1));
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
結果:
分析:
筆試題7:
#include <stdio.h>
int main()
{
char* a[] = { "work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
結果:
分析:
筆試題8:
#include <stdio.h>
int main()
{
char* c[] = { "ENTER","NEW","POINT","FIRST" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *-- * ++cpp + 3);
printf("%s\n", *cpp[-2] + 3);
printf("%s\n", cpp[-1][-1] + 1);
return 0;
}
結果:
分析:
這里必須把內(nèi)存布局畫出來,才能清晰的觀察指針的動向。
注意:cpp
進行++
或--
操作后,指針的指向是要發(fā)生變化的。
本篇有關C語言指針進階的練習就到此結束了,希望你能從中學習到在面對指針問題時,盡量畫出指針的內(nèi)存操作圖,進而解題的思路。
重點說三遍:
畫圖!
畫圖!!
還是畫圖!?。?/strong>
如果你還有什么問題可以評論區(qū)討論或私信我哦。??
下一篇文章將會對前面C語言指針【進階】中的qsort函數(shù)
的模擬實現(xiàn)寫一篇博客,保證簡單易懂,看完就會。
再往后我們會對字符串的研究進行深入了解,并講解一系列關鍵的字符串函數(shù)和內(nèi)存函數(shù),和它們的模擬實現(xiàn)。文章來源:http://www.zghlxwxcb.cn/news/detail-432634.html
感興趣的的小伙伴點點贊,點點關注,謝謝大家的閱讀哦?。?!
點點關注,后期不錯過哦。??
你們的鼓勵就是我的動力,歡迎下次繼續(xù)閱讀?。?!??????文章來源地址http://www.zghlxwxcb.cn/news/detail-432634.html
到了這里,關于C語言:指針【進階】習題練習及分析講解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!