C語言-第七章、用指針實現程序的靈活設計

 

7_1  指針的基本概念數組

_1.1   地址與指針 函數

C語言中一般把地址成爲指針。指針

_1.2  內存單元的指針與內存單元的內容code

_1.3  變量的指針對象

變量的指針就是變量的地址內存

_1.4  直接訪問與間接訪問字符串

7_2  指向變量的指針變量input

_2.1  指針變量的定義原型

形式:基類型說明符  *變量名                   如:int  *p1string

「*」也是一個說明符,p1是一個指針變量。

_2.2  指針變量的引用

1.  指針的專用運算符

 

(1) 取地址運算符&             例:&變量名

(2)指針運算符*                    例:*變量名

2.指針變量的賦值

(1)指針變量的初始化

int a;
int *ap=&a;    /*定義指向總體變量a的指針變量ap*/

(2) 賦值語句:

①int *ap=&a,a;   /*錯誤,不能把未定義的變量a的地址賦給ap*/
/*不容許把一個數賦予指針變量,被賦值的指針變量前也不能再加「*」說明符。*/
//②錯例:
int  *p;
p=1000;        /*不能把一個數賦予指針變量*/
*p=&a;         /*被賦值的指針變量前不能再加「*」說明符*/

(3)將已被賦值的指針變量的值賦給另外一指針變量

int a,*ap,*bp;
ap=&a;       /*使指針變量ap指向變量a*/
bp=ap;       /*將指針變量ap的值賦給指針變量bp;執行該語句後ap和bp都指向同一變量a*/

注:只有相同類型的指針變量之間能夠相互賦值。

錯例:

int a=3,*ap=&a;
float bp;
bp=ap;     /*錯誤,指針變量bp只能指向float型變量(只能保存float型變量的地址)*/

(4) 能夠給指針變量賦0值如:

char  *p=0;

該指針稱爲空指針,爲了程序的可讀性,一般符號常量NULL來表示空指針的值。如:

char *p=NULL;

3.  指針變量加減一個整數

一個指針加一個整數,表示將指針後移;相反,一個指針減一個整數,表示將指針前移。

4.  兩個同類指針變量相減

用於數組,差值表示兩個指針變量之間相隔的元素個數

5.  兩個同類指針變量做比較運算

用於判斷前後關係

6.  指針變量的引用舉例

【例7-1】 經過指針變量引用變量的值

#include<stdio.h>
int main()
{
    int a,b;
	int *ap,*bp;
	a=100;
	b=10;
	ap=&a;
	bp=&b;
	printf("%d,%d\n",a,b);
	printf("%d,%d\n",*ap,*bp);
	return 0;
}

例7-2】 指針變量及其簡單運算

#include<stdio.h>
int main()
{
    int x=3,y,*xp=&x;
	y=*xp+5;
	printf("y=%d\n",y);
	y=++*xp;
	printf("%d\n",y);
	y=*xp++;
	printf("x=%d,y=%d\n",x,y);     /*表示把x的值賦給y再使xp後移,即等價於y=*xp;xp++;*/
	return 0;
}

注:「++」和「*」的運算優先級相同且都是自右向左。

_2.2  指針變量做爲函數參數

【例7-3】 用通常變量做爲參數,不能實現交換。

#include<stdio.h>
int main()
{
    int swap(int x,int y);
	int a=100,b=10;
	printf("%d,%d\n",a,b);
	swap(a,b);
	printf("%d,%d\n",a,b);
	return 0;
}
int swap(int x,int y)  /*交換指針變量ap,bp所指向是地址單元中的內存*/
{
    int temp;
	temp=x;
	x=y;
	y=temp;
}

【例7-4】若改寫爲指針函數爲參數便可交換。

#include<stdio.h>
int main()
{
    int swap(int *ap,int *bp);
	int a=100,b=10;
	printf("%d,%d\n",a,b);
	swap(&a,&b);
	printf("%d,%d\n",a,b);
	return 0;
}
int swap(int *ap,int *bp)  /*交換指針變量ap,bp所指向是地址單元中的內存*/
{
    int temp;
	temp=*ap;
	*ap=*bp;
	*bp=temp;
}

7_3指針與數組

_3.1  指針與一維數組

1.  指向數組元素的指針變量

形式:基類型說明符  *指針變量  如:

int a[10];
int *p;
p=&a[0];

C語言規定,把數組的首地址稱爲數組的指針。

(1)p、a、&a[0]均指向同一單元,它們是數組a的首地址,可是p是指針變量,而a、&a[0]都是指針常量。

2.  經過指針引用數組元素

三種方法:①下標法         ②常量指針法           ③指針變量法。

(1)下標法

#include<stdio.h>
int main()
{
	int a[5],i;
	printf("Please input 5 numbers:");
    for (i=0;i<5;i++)
		scanf("%d",&a[i]);
	for (i=0;i<5;i++)
		printf("a[%d]=%-4d",i,a[i]);
	printf("\n");
	return 0;
}

(2)常量指針法:

#include<stdio.h>
int main()
{
	int a[5],i;
	printf("Please input 5 numbers:");
    for (i=0;i<5;i++)
		scanf("%d",a+i);
	for (i=0;i<5;i++)
		printf("a[%d]=%-4d",i,*(a+i));
	printf("\n");
	return 0;
}

(3)指針變量法:

#include<stdio.h>
int main()
{
	int a[5],i,*p=a;
	printf("Please input 5 numbers:");
    for (i=0;i<5;i++)
		scanf("%d",p+i);
	for (i=0;i<5;i++)
		printf("a[%d]=%-4d",i,*(p+i));
	printf("\n");
	return 0;
}

(4)指針帶下標法:

#include<stdio.h>
int main()
{
	int a[5],i,*p=a;
	printf("Please input 5 numbers:");
    for (i=0;i<5;i++)
		scanf("%d",&p[i]);
	for (i=0;i<5;i++)
		printf("a[%d]=%-4d",i,p[i]);
	printf("\n");
	return 0;
}

(5)逐個移動指針法:

#include<stdio.h>
int main()
{
	int a[5],i,*p=a;
	printf("Please input 5 numbers:");
    for (i=0;i<5;i++)
		scanf("%d",p++);
	p=a;
	for (i=0;i<5;i++)
		printf("a[%d]=%-4d",i,*p++);
	printf("\n");
	return 0;
}

3.用數組的指針做爲函數的參數

【例7-7】用冒泡法對10個整數按升序排列

#include<stdio.h>
#define N 5
int main()
{
	void output(int *p,int n);
	void sort (int x[],int n);
	int a[N],i,*p;
	printf("請輸入%d個整數:\n",N);
    for (i=0;i<N;i++)
		scanf("%d",&a[i]);
	printf("\n");
	printf("原數組以下:\n");
	output (a,N);
    p=a;
	sort (p,N);
	printf("升序結果以下:\n");
    output (a,N);
	return 0;
}
void output (int *p,int n)
{   int i;
    for(i=0;i<n;i++)
		printf("%-4d",*(p+i));
	printf("\n");
}
void sort (int x[],int n)
{   int i,j,k,t;
    for(i=0;i<n-1;i++)
	{
		for (j=0;j<n-i-1;j++)
			if (x[j]>x[j+1])
			{t=x[j];x[j]=x[j+1];x[j+1]=t;}
	}
}

_3.2  指針與多維數組

1.多維數組的地址

2.指向二維數組元素的指針變量

【例7-9】用指針變量輸入多維數組的值

#include<stdio.h>
int main()
{
	int a[2][3]={{1,2,3},{4,5,6}},i;
	int *p=a[0];
    for (i=0;i<6;i++)
	{
		printf("%-4d",p[i]);
		if ((i+1)%3==0)  printf("\n");
	}
	return 0;
}

3.指向一維數組的指針變量

形式:類型說明符  (*指針變量名)[長度];如:

int (*p)[3];

【例7-10】用指向一維數組的指針變量輸出二維數組中的各元素值。

#include<stdio.h>
int main()
{
	int a[2][3]={1,2,3,4,5,6};
	int *(p)[3];
    int i,j;
    for (i=0;i<2;i++)
	{
	    for (j=0;j<3;j++)
			printf("%-4d",*(*(p+i)+j));
		printf("\n");
	}
	return 0;
}

7_4  字符串與指針

_4.1  字符指針的定義與引用

對指向字符變量的指針變量應賦予該字符變量的地址。如:

char  c,*p=&c;

對指向字符串的指針變量應賦予一個字符串的首地址,如:

char  c,*p="China";

等效於:char  *p;     p="China";

【例7-11】用字符指針處理字符數組中的字符串

#include<stdio.h>
int main()
{
    char s[]="China";
	char *p=s;
    while (*p!='\0')
    {
    putchar(*p);
    p++;
    }
    printf("\n");
    return 0;
}

【例7-12】用字符指針處理字符串

#include<stdio.h>
int main()
{
    char s[]="China";
	char *p=s;
    printf("%s\n",p);
    return 0;
}

_4.2  字符指針做爲函數參數

【例7-14】對字符串內容做修改

#include<stdio.h>
void change (char *s)
{
   s[2]='r';
}
int main()
{    char a[]="file";
     change (a);
	 printf("%s\n",a);
	 return 0;
}

7_5  指針數組

_5.1  用指針數組處理二維數組

【例7-15】  用指針數組處理二維數組

#include<stdio.h>
int main()
{
    int a[2][3]={{1,2,3},{4,5,6}},i,j;
	int *pa[2];         /*定義數組pa,它的兩個數組pa[0]和pa[1]都是存放指針變量的*/
	pa[0]=a[0];
	pa[1]=a[1];
	for (i=0;i<2;i++)
    {    for (j=0;j<3;j++)
	    printf("%-4d",*(pa[i]+j));
		printf("\n");
	}
    return 0;
}

_5.2  用字符指針數組處理一組字符串

【例7-16】  用冒泡法對字符按字母順序升序排列

#include<stdio.h>
#include<string.h>
void sort (char *a[],int n)
{   int i,j;
    char *t;
	for (i=0;i<n-1;i++)
		for (j=0;j<n-i-1;j++)
		if (strcmp (a[j],a[j+1])>0)
		{t=a[j];a[j]=a[j+1];a[j+1]=t;}
}
int main()
{   char *p[5]={"Basic","Pascal","Fortran","C","Java"};
    int i;
	sort (p,5);
	for(i=0;i<5;i++)
		printf("%s\n",p[i]);
	return 0;
}

 

7_6  指向指針的指針

二級指針的定義格式:  類型說明符  **指針變量名;  如:

int  **p;

#include<stdio.h>
int main()
{   char *pa[5]={"Basic","Pascal","Fortran","C","Java"};
    char **p;
	p=pa;
	while (pa<pa+5)
	{
		printf("%s\n",*p);
		p++;
	}
	return 0;
}

 

 

 

7_7  指針與函數

_7.1  指針型函數

指針型函數:返回指針值的函數

形式:類型說明符  *函數名(形參表列)

{

……         /*函數體*/

}

【例7-18】輸入一個1~7之間的函數,輸出對應星期名的英語單詞。

#include<stdio.h>
char *day_name(int n)
{
	char *name[]={"Monday ","Tuseday","Wednesday","Thursday","Friday","Saturday","Sunday"};
	return (name[n-1]);
}
int main()
{   int i;
    char *day_name(int n);
	printf("\t星期名對應的英文單詞查詢\n請輸入一個1~7之間的整數:");
	scanf("%d",&i);
	while (i<1||i>7)
	{
		printf("出錯!,請從新輸入:");
		scanf("%d",&i);
	}
	printf("星期%d對應的英語單詞:%s\n",i,day_name(i));
	return 0;
}

_7.2  指向函數的指針變量

格式:類型說明符 (*指針變量名)();如:

int  (*p)();

 

【例7-19】 求兩數較大者

#include<stdio.h>
int max(int a,int b)
{   if(a>b)
    return a;
    else return b;
}
int main()
{
	int x,y,z;
	int (*p)();
	p=max;
	printf("請輸入兩個整數(用逗號分隔):\n");
    scanf("%d,%d",&x,&y);
	z=(*p)(x,y);
	printf("兩數中較大者爲:%d\n",z);
	return 0;
}

 

7_8  指針應用過程當中的注意事項

1.  要準確理解指針的含義,區別指針和指針變量的不一樣含義。

2.  在對數組進行操做時,要能正確的使用指針。

3.  讀者須對各類有關的指針變量定義形式加深理解。

4.  void指針,即「指向空類型的指針」,是指不指向具體數據對象的指針。

5.  指針還能夠實現對動態分配的內存空間進行有效的管理。

 

C語言中,經常使用malloc()和free()這兩個函數以及sizeof運算符動態分配和釋放內存空間。

malloc()函數和free()函數所需的信息一般在頭文件stdio.h 中,其函數原型及功能以下:

(1)malloc()函數

函數原型:

void  *malloc (unsigned size)

功能:從內存分配一個大小爲size個字節的內存空間。若是分配成功,返回新分配內存的首地址;若是沒有足夠的內存分配,則返回NULL。

爲確保內存分配準確,函數malloc()一般和運算符sizeof 一塊兒使用。例:

int *p;
p=(int* )malloc(20*sizeof(int));/*分配20個所需的內存空間*/

(2)  free函數

函數原型:void free(void *p);

功能:釋放由指針變量p所指向的內存塊,無返回值。如:

int *p;
p=(int* )malloc(20*sizeof(int));/*分配20個所需的內存空間*/
……
free(p);

【例7-20】  輸入n名學生的C語言成績,並將這些成績逆序輸出。

#include<stdio.h>
int main()
{
	float *score;
	int n,i;
	printf("請輸入學生人數:");
	scanf("%d",&n);
	score=(float*)malloc(n*sizeof(float));
	if(!score) 
		printf("分配空間失敗!\n");
	else 
	{
		printf("請輸入%d個學生的成績(空格分隔):\n",n);
		for (i=0;i<n;i++)
			scanf("%f",score+i);
		printf("逆向輸出各成績以下:\n");
		for (i=n-1;i>=0;i--)
			printf("%7.2f",score[i]);
		printf("\n");
		free(score);
	}
	return 0;
}
相關文章
相關標籤/搜索