C語言之指針的應用

&運算符

指針是 c 語言最重要的概念之一,用於存儲變量的地址。&運算符給出變量的存儲地址,可以把地址看作變量在內存中的位置。

指針

指針是一個值爲內存地址的變量(或數據對象),指針變量的值是地址。

ptr = &pooh;   //把 pooh 的地址賦給 ptr,可以說 “ptr 指向 pooh”

*間接運算符

後跟指針表示給出儲存在指針指向地址上的值,也可直接跟地址。

聲明指針

  • 聲明指針變量時必須指定指針所指向變量的類型,不同的變量類型佔用不同的存儲空間
int * pi;    // “ * ” 表示聲明的變量是指針
             //語句含義:pi 是一個指針,*pi 是 int 類型
             //pi 是什麼類型?描述的類型是“指向 int 類型的指針”
             //pi 的值是一個地址,由無符號整數表示,不要認爲是整數類型,所以指針實際上是一個新類型。
             //通常聲明時 * 後加空格,在引用變量時省略空格
  • 指針運用,解決函數間通信問題,代碼示例
#include<stdio.h>
void swap(int* u, int* v);
int main(void)
{
	int x = 5;
	int y = 10;
	printf("Originally x = %d and y = %d\n", x, y);
	swap(&x, &y);   //傳遞的是地址,不是值
	printf("Now x = %d and y = %d\n", x, y);
	return 0;
}
void swap(int* u, int* v)    //u,v 是指向整數的指針
{
	int temp;
	temp = *u;     //取地址上的值
	*u = *v;
	*v = temp;
}
  • 運行結果
    在這裏插入圖片描述

指針與數組

數組表示法其實是變相地址使用指針

  • 重點
  1. 數組名是數組首元素的地址,如果 flizny 是一個數組,下面的語句成立:
flizny == &flizny[0];
  1. C 語言中,指針 “+1”指的是增加一個存儲單元。數組中,加1後的地址是下一個元素的地址,而不是下一個字節的地址,也就是遞增它所指向類型的大小。這也是爲什麼必須聲明指針所指向對象類型原因之一。
    在這裏插入圖片描述
  2. C 語言標準在描述數組表示法時藉助了指針,定義 arr[n] 的意思是 *(arr + n)。可以認爲是“到內存的 arr 位置,然後移動 n 個單元,檢索在那裏的值。”
dates + 2 == &dates[2]        //相同的地址
*(dates + 2) == dates[2]      //相同的值
  1. 只有在函數原型或函數定義頭中,纔可以用 int ar[] 代替 int* ar,都表示 ar 是指向 int 類型的指針。
int sum(int* ar, int n);      //等價於下面
int sum1(int ar[], int n);
  • 代碼示例
#include<stdio.h>
#define SIZE 4
#define MONTHS 12
int sum(int* ar, int n);
int sum1(int ar[], int n);
int sump(int* start, int* end);
int main(void)
{
	short* pi;
	short array[SIZE];
	int index;
	int answer, answer1,answer2;
	int days[MONTHS] = {31,28,31,30,31,30,31,31,30,31,30,31};
	pi = array;       //把數組地址賦給指針,也就是首元素地址
	for (index = 0; index < SIZE; index++)
		printf("pointers + %d: %10p\n", index, pi + index);

	for (index = 0; index < MONTHS; index++)
	{
		printf("Month %2d has %d days.\n", index + 1,
			*(days + index));   //與 days[index] 值相同
	}
	answer = sum(days, MONTHS);
	answer1 = sum1(days, MONTHS);
	answer2 = sump(days, days + MONTHS);
	printf("The size of days is %zd bytes.\n", sizeof days);
	printf("The total number of days is %ld.\n", answer);
	printf("The total number of days is %ld.\n", answer1);
	printf("The total number of days is %ld.\n", answer2);
	return 0;
}
int sum(int* ar, int n)
{
	int total = 0;
	for (int i = 0; i < n; i++)
		total += ar[i];         //ar[i] 與 *(ar + i) 相同 
	return total;
}
int sum1(int ar[], int n)        //數組表示法
{
	int total = 0;
	for (int i = 0; i < n; i++)
		total += ar[i];         //ar[i] 與 *(ar + i) 相同 
	return total;
}
int sump(int* start, int* end)  //指針表示法
{
	int total = 0;
	while (start < end)
	{
		total += *start++;
	}
	return total;
}

運行結果
在這裏插入圖片描述

const用法

  1. 如果編寫的函數需要修改數組,那麼聲明數組形參時不使用 const;如果編寫的函數不用修改數組,那麼聲明數組形參時最好使用 const。
int sum(const int ar[], int n);      //不需要修改原數組
int sum1(int ar[], int n);           //需要修改原數組	
  1. 指向 const 的指針不能用於改變值。
int rates[2] = {1,2};
const int* p = rates;
*p = 123;                //不允許
p[1] = 3;                //不允許
rates[1] = 3;            //允許
p++;                     //可以讓指針指向別處
  1. 非 const 數據的地址既可以賦給普通指針又可以賦給指向 const 的指針,const 數據的地址只能賦給指向 const 的指針。
int arr[3] = {1,2,3};
const int locked[4] = {5,6,7,8};
int* p = arr;            //有效
const int* pn = arr;     //有效
pn = &arr[2];            //有效

p = locked;              //無效
pn = locked;             //有效
  1. 聲明並初始化一個不能指向別處的指針。
int array[3] = {32,12,34};
int* const p = array;
const int* const p1 = array;  //既不能改變指針指向的地址又不能改變地址上的值
p = &array[2];          //無效
*p = 11;                //有效

*p1 = 12;               //無效
p1 = &array[2];         //無效

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章