標(biāo)題:
如何學(xué)好C語(yǔ)言-指針
[打印本頁(yè)]
作者:
edu118gct
時(shí)間:
2014-12-5 10:46
標(biāo)題:
如何學(xué)好C語(yǔ)言-指針
復(fù)習(xí)運(yùn)算符
(關(guān)系運(yùn)算與邏輯運(yùn)算)
#include "stdio.h"
void main()
{
int a=1,b=2,m=0,n=0,k;printf("%d\n",m);
k=(n=b>a)||(m=a<b); printf("%d\n",m);
printf("%d,%d\n",k,m);
}
(條件運(yùn)算,與逗號(hào)運(yùn)算)
#include "stdio.h"
void main()
{
char a=1,b=3,c=0;
printf("%d",(a+b>a-b?a++:++b,++a,b+5));
}//%d 整形輸出 %c 字符 %s 字符串 %f 浮點(diǎn)
復(fù)習(xí)函數(shù)(帶形參的返回函數(shù)值可以做判斷語(yǔ)句的條件)
#include “stdio.h”
char delay(char t);
char delay(char t) //t=3
{
t++; //t=4
return t;
}
void main()
{
char i=8,k;
if(i>delay(2))
{
k=delay(3); //k=4
i++; //i=9
printf("k=%d,i=%d",k,i);
}
}
復(fù)習(xí)全局變量做形參其值不變
#include "stdio.h"
void delay(int y);
int y=3;
void delay(int y) //y=5
{
for(;y<6;y++);
printf("y1=%d\n",y); //y=6
}
void main()
{
int mm;
delay(5);
printf("y2=%d\n",y); //y=3
mm=y++; //mn=3,y=4
printf("y3=%d\n",y);
指針數(shù)組(里面存放的是指針,如果是字符串則存放的是字符串的首地址)
#include "stdio.h"
void main()
{
char i=0,*p[3]={"wejlj","dsag","dsfads"} ;
for(;i<3;i++)
{
printf("%c \n",*(p[i]));
}
}
#include "stdio.h"
main(){
int a[3][3]={1,2,3,4,5,6,7,8,9};
int *pa[3]={a[0],a[1],a[2]};
int *p=a[0];
int i;
for(i=0;i<3;i++)
printf("%d,%d,%d\n",a[i][2-i],*a[i],*(*(a+i)+i));
for(i=0;i<3;i++)
printf("%d,%d,%d\n",*pa[i],p[i],*(p+i));
}
指針函數(shù)與函數(shù)指針的區(qū)別
1、指針函數(shù)是指帶指針的函數(shù),即本質(zhì)是一個(gè)函數(shù)。函數(shù)返回類(lèi)型是某一類(lèi)型的指針
類(lèi)型標(biāo)識(shí)符 *函數(shù)名(類(lèi)型 參數(shù)表)
int *f(int x,int y);
首先它是一個(gè)函數(shù),只不過(guò)這個(gè)函數(shù)的返回值是一個(gè)地址值。函數(shù)返回值必須用同類(lèi)型的指針變量來(lái)接受,也就是說(shuō),指針函數(shù)一定有函數(shù)返回值,而且,在主調(diào)函數(shù)中,函數(shù)返回值必須賦給同類(lèi)型的指針變量。
表示:
float *fun();
float *p;
p = fun(a);
注意指針函數(shù)與函數(shù)指針表示方法的不同,千萬(wàn)不要混淆。最簡(jiǎn)單的辨別方式就是看函數(shù)名前面的指針*號(hào)有沒(méi)有被括號(hào)()包含,如果被包含就是函數(shù)指針,反之則是指針函數(shù)。
來(lái)講詳細(xì)一些吧!請(qǐng)看下面
指針函數(shù):
當(dāng)一個(gè)函數(shù)聲明其返回值為一個(gè)指針時(shí),實(shí)際上就是返回一個(gè)地址給調(diào)用函數(shù),以用于需要指針或地址的表達(dá)式中。
格式:
類(lèi)型說(shuō)明符 * 函數(shù)名(參數(shù))
當(dāng)然了,由于返回的是一個(gè)地址,所以類(lèi)型說(shuō)明符一般都是int。
例如:int *GetDate(void);
int * aaa(int,int);
函數(shù)返回的是一個(gè)地址值,經(jīng)常使用在返回?cái)?shù)組的某一元素地址上。
#include "stdio.h"
int * GetDate(int wk,int dy);
main()
{
int wk,dy;
do
{
printf("Enter week(1-5)day(1-7)\n");
scanf("%d%d",&wk,&dy);
}
while(wk<1||wk>5||dy<1||dy>7); // wk=2;dy=3
printf("%d\n",*GetDate(wk,dy));
}
int * GetDate(int wk,int dy)
{
static int calendar[5][7]=
{
{1,2,3,4,5,6,7},
{8,9,10,11,12,13,14},
{15,16,17,18,19,20,21},
{22,23,24,25,26,27,28},
{29,30,31,-1}
}; //不釋放空間
return &calendar[wk-1][dy-1]; //1,2
}
程序應(yīng)該是很好理解的,子函數(shù)返回的是數(shù)組某元素的地址。輸出的是這個(gè)地址里的值。
#include "stdio.h"
main(){
int i;
char *day_name(int n);
printf("input Day No:\n");
scanf("%d",&i);
if(i<0) exit(1);
printf("Day No:%2d-->%s\n",i,day_name(i));
}
char *day_name(int n){
static char *name[]={ "Illegal day",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday" };
return((n<1||n>7) ? name[0] : name[n]);
}
2、函數(shù)指針是指向函數(shù)的指針變量,即本質(zhì)是一個(gè)指針變量。
類(lèi)型說(shuō)明符 (*函數(shù)名)(參數(shù))
int (*f) (int x); /* 聲明一個(gè)函數(shù)指針 */
f=func; /* 將func函數(shù)的首地址賦給指針f */
指向函數(shù)的指針包含了函數(shù)的地址,可以通過(guò)它來(lái)調(diào)用函數(shù)。聲明格式如下:
類(lèi)型說(shuō)明符 (*函數(shù)名)(參數(shù))
其實(shí)這里不能稱(chēng)為函數(shù)名,應(yīng)該叫做指針的變量名。這個(gè)特殊的指針指向一個(gè)返回整型值的函數(shù)。指針的聲明必須和它指向函數(shù)的聲明保持一致。
指針名和指針運(yùn)算符外面的括號(hào)改變了默認(rèn)的運(yùn)算符優(yōu)先級(jí)。如果沒(méi)有圓括號(hào),就變成了一個(gè)返回整型指針的函數(shù)的原型聲明。
例如:
void (*fptr)();
把函數(shù)的地址賦值給函數(shù)指針,可以采用下面兩種形式:
fptr=&Function;
fptr=Function;
取地址運(yùn)算符&不是必需的,因?yàn)閱螁我粋(gè)函數(shù)標(biāo)識(shí)符就標(biāo)號(hào)表示了它的地址,如果是函數(shù)調(diào)用,還必須包含一個(gè)圓括號(hào)括起來(lái)的參數(shù)表。
可以采用如下兩種方式來(lái)通過(guò)指針調(diào)用函數(shù):
x=(*fptr)();
x=fptr();
第二種格式看上去和函數(shù)調(diào)用無(wú)異。但是有些程序員傾向于使用第一種格式,因?yàn)樗鞔_指出是通過(guò)指針而非函數(shù)名來(lái)調(diào)用函數(shù)的。下面舉一個(gè)例子:
#include "stdio.h"
void (*funcp)();
void FileFunc(),EditFunc();
main()
{
funcp=FileFunc;
(*funcp)();
funcp=EditFunc;
(*funcp)();
}
void FileFunc()
{
printf("FileFunc\n");
}
void EditFunc()
{
printf("EditFunc\n");
}
程序輸出為:
FileFunc
EditFunc
例2
#include"stdio.h"
//定義一個(gè)函數(shù)指針,形參為一個(gè)char類(lèi)型,一個(gè)int類(lèi)型,返回類(lèi)型為void
void (*pf)(char, int);
void fun(char ,int); //聲明一個(gè)函數(shù),形參為一個(gè)char類(lèi)型,一個(gè)int類(lèi)型,返回類(lèi)型為void
int main(void)
{
pf=fun; //給函數(shù)指針pf賦值為fun函數(shù)的首地址(函數(shù)名代表函數(shù)的首地址)
(*pf)('c',372); //調(diào)用pf指向的函數(shù)
}
void fun(char a,int b)
{
printf("the argument is %c and %d\n",a,b);
}
主要的區(qū)別是一個(gè)是指針變量,一個(gè)是函數(shù)。在使用是必要要搞清楚才能正確使用
二、指針的指針
指針的指針看上去有些令人費(fèi)解。它們的聲明有兩個(gè)星號(hào)。例如:
char ** cp;
如果有三個(gè)星號(hào),那就是指針的指針的指針,四個(gè)星號(hào)就是指針的指針的指針的指針,依次類(lèi)推。當(dāng)你熟悉了簡(jiǎn)單的例子以后,就可以應(yīng)付復(fù)雜的情況了。當(dāng)然,實(shí)際程序中,一般也只用到 二級(jí)指針,三個(gè)星號(hào)不常見(jiàn),更別說(shuō)四個(gè)星號(hào)了。
指針的指針需要用到指針的地址。
char c='A';
char *p=&c;
char **cp=&p;
通過(guò)指針的指針,不僅可以訪(fǎng)問(wèn)它指向的指針,還可以訪(fǎng)問(wèn)它指向的指針?biāo)赶虻臄?shù)據(jù)。下面就是幾個(gè)這樣的例子:
char **p1=*cp;
char c1=**p1;
你可能想知道這樣的結(jié)構(gòu)有什么用。利用指針的指針可以允許被調(diào)用函數(shù)修改局部指針變量和處理指針數(shù)組。
#include "stdio.h"
void FindCredit(int **);
main()
{
int vals[]={7,6,5,-4,3,2,1,0};
int *fp=vals;
FindCredit(&fp);
printf("%d\n",*fp);
}
void FindCredit(int ** sp)
{
while(**sp!=0)
if(**sp<0) break;
else (*fpp)++;
}
首先用一個(gè)數(shù)組的地址初始化指針fp,然后把該指針的地址作為實(shí)參傳遞給函數(shù)FindCredit()。FindCredit()函數(shù)通過(guò)表達(dá)式**fpp間接地得到數(shù)組中的數(shù)據(jù)。為遍歷數(shù)組以找到一個(gè)負(fù)值,F(xiàn)indCredit()函數(shù)進(jìn)行自增運(yùn)算的對(duì)象是調(diào)用者的指向數(shù)組的指針,而不是它自己的指向調(diào)用者指針的指針。語(yǔ)句(*fpp)++就是對(duì)形參指針指向的指針進(jìn)行自增運(yùn)算的。但是因?yàn)?運(yùn)算符高于++運(yùn)算符,所以圓括號(hào)在這里是必須的,如果沒(méi)有圓括號(hào),那么++運(yùn)算符將作用于二重指針fpp上。
三、指向指針數(shù)組的指針
指針的指針另一用法舊處理指針數(shù)組。有些程序員喜歡用指針數(shù)組來(lái)代替多維數(shù)組,一個(gè)常見(jiàn)的用法就是處理字符串。
#include "stdio.h"
char *Names[]={"Bill","Sam","Jim","Paul","Charles","0"};
main()
{
char **nm=Names;
while(**nm!=‘0’)
printf("%s\n",*nm++);
}
先用字符型指針數(shù)組Names的地址來(lái)初始化指針nm。每次printf()的調(diào)用都首先傳遞指針nm指向的字符型指針,然后對(duì)nm進(jìn)行自增運(yùn)算使其指向數(shù)組的下一個(gè)元素(還是指針)。注意完成上述認(rèn)為的語(yǔ)法為*nm++,它首先取得指針指向的內(nèi)容,然后使指針自增。
深圳廣州南寧長(zhǎng)沙鄭州嵌入式單片機(jī)C語(yǔ)言技術(shù)提升聯(lián)系郭老師qq754634522,年底優(yōu)惠多多,添加咨詢(xún)可免費(fèi)領(lǐng)取學(xué)習(xí)優(yōu)惠券哦
注意數(shù)組中的最后一個(gè)元素被初始化為0,while循環(huán)以次來(lái)判斷是否到了數(shù)組末尾。具有零值的指針常常被用做循環(huán)數(shù)組的終止符。程序員稱(chēng)零值指針為空指針(NULL)。采用空指針作為終止符,在數(shù)組增刪元素時(shí),就不必改動(dòng)數(shù)組的代碼,因?yàn)榇藭r(shí)數(shù)組仍然以空指針作為結(jié)束。
#include "stdio.h"
main()
{
char *name[]=
{"Follow me","BASIC","Great Wall","FORTRAN","Computer desighn"};
char **p;
int i;
for(i=0;i<5;i++)
{
p=name+i;
printf("%s\n",*p);
}
}
/* typedef與define之間的區(qū)別*/
#include "stdio.h"
#define PIN1 int *
typedef int * PIN2;
void main()
{
PIN1 a=1,b=1;
PIN2 c=3,d=3;
printf("%d",a); //a是 指針 1
printf("\n");
printf("%d",a+1); //a地址加1,由于是整型占4個(gè)字節(jié) 5
printf("\n");
printf("%d",b); //b是 整型 值 1
printf("\n");
printf("%d",b+1); //b的值自增1 2
printf("\n");
printf("%d",c); //c是 指針 1
printf("\n");
printf("%d",c+1); //c地址加1,由于是整型占4個(gè)字節(jié) 5
printf("\n");
printf("%d",d); //d是 指針 1
printf("\n");
printf("%d",d+1); //d地址加1,由于是整型占4個(gè)字節(jié) 5
}
作者:
bhjyqjs
時(shí)間:
2015-6-2 10:17
很容易混淆的東西,慢慢學(xué)習(xí)吧
作者:
verycq
時(shí)間:
2015-6-2 21:12
這東西可以說(shuō)是學(xué)習(xí)的瓶頸啊。不過(guò)學(xué)會(huì)了,也簡(jiǎn)單。
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1