C語言指標(三):陣列指標和字串指標

Miracle_ICdv發表於2020-11-18

前面已經介紹了最基本的指標概念指標(一)以及二級指標,接下來我們學習指標在陣列和字串中的應用。

陣列指標

通過指標遍歷陣列(一)

首先我們給出一個陣列,如何通過指標來遍歷陣列中所有元素?

#include <stdio.h>
int main(){
    int arr[] = { 1, 2, 3, 4, 5 };
    /*
	sizeof(arr)就是整個陣列所有元素一共佔用的記憶體大小
	sizeof(int)就是一個int型資料佔用的記憶體大小
	sizeof(arr) / sizeof(int)就是陣列的長度
	*/
    int len = sizeof(arr) / sizeof(int);  //求陣列長度
    										
    int i;
    for(i=0; i<len; i++){
    /*
	arr 是陣列名,指向陣列的第 0 個元素,表示陣列首地址
	arr+i 指向陣列的第 i 個元素,*(arr+i) 表示取第 i 個元素的資料
	*/
        printf("%d  ", *(arr+i) );  //*(arr+i)等價於arr[i]
    }
    printf("\n");
    return 0;
}

執行結果:
在這裡插入圖片描述

通過指標遍歷陣列(二)

我們通過另外一種方式,單獨定義一個指標,指向陣列

#include <stdio.h>

int main(){
    int arr[] = { 1, 3, 5, 7, 9 };
    int i, *p = arr, len = sizeof(arr) / sizeof(int);

    for(i=0; i<len; i++){
        printf("%d  ", *(p+i) );
    }
    printf("\n");
    return 0;
}

執行結果:
在這裡插入圖片描述

通過指標遍歷陣列(三)

對指標變數進行加法和減法運算時,是根據資料型別的長度來計算的。如果一個指標變數 p 指向了陣列的開頭,那麼 p+i 就指向陣列的第 i 個元素;如果 p 指向了陣列的第 n 個元素,那麼 p+i 就是指向第 n+i 個元素;而不管 p 指向了陣列的第幾個元素,p+1 總是指向下一個元素,p-1 也總是指向上一個元素。

#include <stdio.h>

int main(){
    int arr[] = { 1, 3, 5, 7, 9 };
    int *p = &arr[2];  //也可以寫作 int *p = arr + 2;

    printf("%d, %d, %d, %d, %d\n", *(p-2), *(p-1), *p, *(p+1), *(p+2) );
    return 0;
}

執行結果:
在這裡插入圖片描述

通過指標遍歷陣列(四)

藉助自增運算子來遍歷陣列元素:

#include <stdio.h>

int main(){
    int arr[] = { 1, 3, 5, 7, 9 };
    int i, *p = arr, len = sizeof(arr) / sizeof(int);

    for(i=0; i<len; i++){
        printf("%d  ", *p++ );
    }
    printf("\n");
    return 0;
}

執行結果:
在這裡插入圖片描述

陣列指標易混淆點

如果p是指向陣列 arr 中第 n 個元素的指標,那麼 * p++、*++p、(*p)++ 分別是什麼意思呢?

  • *p++ 等價於 *(p++),表示先取得第 n 個元素的值,再將 p 指向下一個元素
  • *++p 等價於 *(++p),會先進行 ++p 運算,使得 p 的值增加,指向下一個元素,整體上相當於 *(p+1),所以會獲得第 n+1 個陣列元素的值。
  • (*p)++ 就非常簡單了,會先取得第 n 個元素的值,再對該元素的值加 1。

陣列元素找最大值

首先我們看下不用指標的方式:

#include <stdio.h>

int max(int s[])
{
	int value = s[0];
	int i;
	for (i = 1;i<10;i++)
	{
		if(value < s[i])
		{
			value = s[i];
		}
	}
	
	return value;
}

int main(){
    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };
    int i = max(buf);
	printf("最大值:%d\n",i);
	
	return 0;
}

執行結果:
在這裡插入圖片描述
現在我們把上面的程式碼改為用指標的方式:

#include <stdio.h>

int max(int *s)
{
	int value = *s;
	int i;
	for (i = 1;i<10;i++)
	{
		if(value < *(s+i))
		{
			value = *(s+i);
		}
	}
	
	return value;
}

int main(){
    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };
    int i = max(buf);
	printf("最大值:%d\n",i);
	
	return 0;
}

執行結果:
在這裡插入圖片描述

陣列逆置

現在我們將一個陣列比如{1,2,3,4,5}變為{5,4,3,2,1},這樣反轉過來。
先看下不用指標的常見做法:

#include <stdio.h>

int printf_buf(int arr[])
{
	int i;
	for(i=0;i<10;i++)
	{
		printf("%d ",arr[i]);
	}	 
	return 0;
}

int main(){
	int low = 0;
	int high = 9;
    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };
	while(low<high)
	{
		int temp = buf[low];
		buf[low] = buf[high];
		buf[high] = temp;
		low++;
		high--;
	}
	
	printf_buf(buf);
	return 0;
}

執行結果:
在這裡插入圖片描述
這個問題也可以用遞迴函式解決,在之前的部落格裡可以看到:遞迴函式
現在我們用指標的方式解決:

#include <stdio.h>

int printf_buf(int arr[])
{
	int i;
	for(i=0;i<10;i++)
	{
		printf("%d ",arr[i]);
	}	 
	return 0;
}

int main(){

    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };

	int *start = &buf[0];
	int *end = &buf[9];
	while(start<end)
	{
		int temp = *start;
		*start = *end;
		*end = temp;
		
		start++;
		end--;
	}
	
	printf_buf(buf);
	return 0;
}

執行結果:
在這裡插入圖片描述
完全正確~

陣列元素找第二大值

當然,這個問題最簡單的就是排個序,找出第二個就行。但是這裡我們要求不進行排序的情況下用指標實現。
我們先來理下思路:

  • 要找到陣列中第二大的數肯定要遍歷陣列
  • 需要逐個對比大小

具體實現:

  1. 第一步,定義兩個變數,max:代表最大,s_max:代表第二大;
  2. 我們假設陣列中第一個元素是最大值,第二個元素是第二大值
  3. 遍歷陣列,如果遇到第i個元素比max大,那麼就讓當前max的值先存放在s_max中,並且把現在的max的值改為當前第i個元素
  4. 如果遇到第n個元素,比max小,但是比s_max大,那麼就把s_max改為這第n個元素
  5. 遍歷完整個陣列後,就找到了第二大的元素s_max;

還是先用陣列下標的方式實現:

#include <stdio.h>

int smax(int s[])
{
	int max;
	int s_max;
	max = s[0];
	s_max = s[1];
	int i;
	for(i=0;i<10;i++)
	{
		if(max < s[i])
		{
			s_max = max;
			max = s[i];
		}
		else if(max > s[i] && s_max < s[i])
		{
			s_max = s[i];
		}
	}
	return s_max;

}

int main()
{
    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };
	printf("第二大的元素是:%d\n",smax(buf));
	
	return 0;
}

執行結果:
在這裡插入圖片描述
結果完全正確,第二大的元素確實是65

現在把上面程式碼改為用指標的方式:

#include <stdio.h>

int smax(int *s)
{
	int max;
	int s_max;
	max = *s;
	s_max = *(s+1);
	int i;
	for(i=0;i<10;i++)
	{
		if(max < *(s+i))
		{
			s_max = max;
			max = *(s+i);
		}
		else if(max > *(s+i) && s_max < *(s+i))
		{
			s_max = *(s+i);
		}
	}
	return s_max;

}

int main()
{
    int buf[] = { 34, 35, 53, 27, 19, 5, 77, 65, 11, 9 };
	printf("第二大的元素是:%d\n",smax(buf));
	
	return 0;
}

執行結果:
在這裡插入圖片描述
完全正確!

字串指標

計算字串長度

我們給出一個字串,通過指標來實現字串長度的計算,不使用陣列下標。

#include <stdio.h>

int main()
{
	char s1[100] = "hello";	
	char *p = s1;
	int len = 0;
	
	while(*p)	//*p的內容為0時,表示字串結束了
	{
		p++;
		len++;
	}
	
	printf("字串長度為%d\n",len);
	return 0;
} 

執行結果:
在這裡插入圖片描述

合併字串

通過指標把兩個字串陣列合併為一個

#include <stdio.h>

int main()
{
	char s1[100] = "hello";	
	char s2[100] = " world"; 
	char *p1 = s1;
	char *p2 = s2;
	
	while(*p1)
	{
		p1++;
	}
	
	while(*p2)
	{
		*p1 = *p2;//從s1的最後開始,從s2的首元素開始 
		p2++;
		p1++;
	}
	
	printf("%s\n",s1);
	return 0;
} 

執行結果:
在這裡插入圖片描述

漢字字串逆置

待續~~~~

相關文章