C语言复习3----指针
指针 指针类型是C语言的一种特殊数据类型,是C语言的精华所在,也是C语言的难点之一。 指针是用来存放地址的变量。这个地址可以是变量的地址,也可以是数组、函数的起始点,还可以是指针的地址。 某个指针存放了哪个变量的地址,就可以说指针指向了这个变量。
指针----间接寻址 p 2000 C语言中,将地址形象化地称为指针,“指向”某个变量的地址。 变量i存放在地址2000中,把地址2000存在另外1个变量p中,这个变量p就是指针类型的变量,它指向变量i。 为了访问变量i,还可以先访问变量p获得变量i的地址,再到这个地址中去访问变量i。 通过指针变量来间接存取它所指向的变量,称为间接寻址。 2000 i
指针变量 例如定义了1个变量i,存放i变量的地址是2000,占用2个字节。再定义另1个变量i_pointer用来存放i变量的地址,为其分配2个字节。我们可以通过以下的句子把变量i的地址(2000)存放到变量i_pointer中。 i_pointer=&i; 这时, i_pointer的值就是2000,即变量i所占用单元的起始地址。 注意:指针变量的值是它所指向的变量的地址,而不是该变量的值。
指针的定义 指针是一种存放地址的变量,必须在使用前定义。指针变量的命名规则与其它变量相同,必须是唯一的标示符。指针定义的格式如下: 类型名 *指针名; 类型名----说明指针所指向的变量类型 星号*----是一个指针运算符,说明*号后面的“指针名”是一个指针而不是一个普通变量。 例如: int *p1; 这个例子中,p1是指向int型的指针变量。
指针有明确的指向 在使用指针之前要使指针有明确的指向。例如: int i,j; int *p1,*p2; p1=&i; p2=&j; 注意:只有整型变量的指针才能指向整型变量。指针变量中只能存放地址,不能将其它数据赋值给一个指针变量。下列是错的: pointer_1=100;
指针有关的运算符 &:取地址运算符 *:指针运算符,取其指向的内容。 例如:&a为变量a的地址,*p为指针p所指向的内存单元的内容。 &运算只能作用于变量或数组的元素,不能作用于数组名或常量。 例如: int a[20],n; 用&n合法,用&a[0]合法,用&a非法。
运算符* 单目运算符*是&的逆运算,*的操作对象是地址。单目运算符*是通过变量的地址而不是变量名存取变量。例如: char c; char *pc; pc=&c; 则表达式 *(&c)和表达式 *pc都表示同一个对象c。 下列语句效果相同: *(&c)='a'; *pc='a'; c='a'; 都是把字符'a'放进变量c。 “&”和“*”这两个运算符优先级相同,但是按自右向左结合,因此对于&*pc,先进行*pc运算,然后再执行&,即变量c的地址。
指针的应用 #include "stdafx.h" void main() { int a,b; int *p1,*p2; p1=&a; p2=&b; printf("%d,%d\n",a,b); printf("%d,%d\n",*p1,*p2); } 运行结果 10,20
指针与数组 一个数组包含有多个元素(数组单元),每个元素都有一个内存地址。 C语言的数组与指针有着密切的关系,可以用指针代替下标引用数组的元素。 当定义1个数组时,C语言会按照其类型和长度在内存中分配一段连续的字节,数组名代表了数组的首地址,也就是在内存中所占的一段连续单元的起始地址,是连续字节的第1个字节的地址。 当我们定义1个指针,使这个指针存放数组第1个元素的地址,就可以说该指针指向了这个数组。
指向一维数组的指针 定义1个长度为10的整型数组: int a[10]; 再定义1个指针变量: int *p; 对指针赋初值: p=&a[0]; 使指针指向了数组的第1个元素的地址,也就是数组的首地址。 注意指针变量的类型必须与要指向的数组类型一致。
其实数组名就代表了数组元素的首地址,也可以用下列语句给指针赋初值: p=a; 把数组a的首地址赋给指针变量p。 也可以在定义指针时写成: int *p=a;
如果p的初值是数组a的首地址,则p+i和a+i就是a[i]的地址,它指向数组a的第i个元素。. (p+i)和 如果p的初值是数组a的首地址,则p+i和a+i就是a[i]的地址,它指向数组a的第i个元素。*(p+i)和*(a+i)是其指向的数组元素,就是a[i]。 实际上C语言在编译时对数组元素a[i]的处理就是处理成*(a+i),按数组首地址加上位移量,得到该元素单元的地址,然后取出该单元的内容。
数组元素的下标引用与指针引用的对应关系 数组元素的下标引用与指针引用的对应关系,假定p指向a[0]: a[0] *p *a … … … a[9] *(p+9) *(a+9) 数组元素的地址的对应关系 &a[0] p a &a[1] p+1 a+1 &a[2] p+2 a+2 … … … &a[9] p+9 a+9 当指针指向数组,可以通过数组名和指针两种方式来访问数组单元。
字符串的指针 在C语言中,字符串指的是在内存中存放的一串以‘\0’结尾的若干个字符。我们知道可以用数组来表达一个字符串。【例7-11】 #include<stdio.h> void main() { char string[]="hello world"; printf("%s\n",string); } 这里的string是数组名,同时代表了字符数组的首地址,和前面学过的数组一样。
利用指针也可以表达字符串 用字符指针指向字符串中的字符。【例7-12】 #include<stdio.h> void main( ) { char *str="hello world"; printf("%s\n",str); } 这里的str指针是指向字符串“hello world”的指针,即字符串的首地址赋给了字符指针,因此说一个字符指针指向了一个字符串。
利用指针也可以表达字符串 C语言对字符串的处理是按字符数组处理的,在内存中开辟了一个字符数组用来存放字符串常量。 所以定义str的部分, char *str="hello world"; 等价于下面2两行: char *str; str="hello world";
用字符指针指向字符串 下面这个例子是用字符指针定义并指向字符串,然后用一维字符数组来显示其内容: #include<stdio.h> void main( ) { char *str=“hello world”; printf(“%s\n”,str); //用指针方式显示 for(int i=0;i<11;i++) //用数组方式显示 printf("%c",str[i]); }
用字符指针指向字符串 例子中并没有定义字符数组,但却可以使用字符数组。因此: char *str="hello world"; 也等价于: 这里的str被定义为一个指向字符型数据的指针变量,只是把字符串的首地址赋给了字符指针,并不是把字符串的所有字符放在str中,也不是把字符串赋给*str。
定义了一个字符指针变量可以用下标形式引用 C语言输出一个字符串时,先输出字符指针指向的第1个字符,然后自动使指针加1指向下一个字符,直到遇到字符串结束标志'\0'为止。 如果定义了一个字符指针变量,并使它指向一个字符串,就可以用下标形式引用指针变量所指向的字符串中的字符。见【例7-13】。
void main() { char. a="hello world"; int i; for(i=0;a[i] void main() { char *a="hello world"; int i; for(i=0;a[i]!='\0';i++) printf("%c",a[i]); printf("\n"); } 【例7-13】
指针数组 指针变量可以同其它变量一样作为数组的元素,如果一个数组的元素是由指针变量组成,这个数组称为指针数组。指针数组的定义形式为: 类型名 *数组名[常量表达式]; 例如: int *a[10]; 此定义说明a是一个指针数组,每个数组元素是一个指向int型变量的指针,此数组由10个元素组成,每个元素都是指针变量。 a是此指针数组的数组名,a为此指针数组中元素a[0]的地址,*a就是a[0],*(a+i)就是a[i]。
指针与函数 指针除了可以作为函数的参数外,还可以指向一个函数,也就是说,指针存放的是函数的入口地址。 函数可以带回指针型的数据,也就是地址。我们可以把函数返回值定义为指向某种类型的指针。
指向函数的指针 对于函数来说,可以像数组那样通过函数名来访问一个函数,也可以通过指向函数的指针来访问一个函数。 函数型指针定义形式如下: 类型标识符 (*指针名称)( ); 例如,定义一个指向返回值为整型的函数指针p如下: Int (*p)( );
指向函数的指针 指向函数的指针是存放函数入口地址的变量。 一个函数的入口地址用函数名来表示,它是函数体内第一个可执行的代码在内存中的地址。 指向函数的指针中存放的就是这个函数的入口地址,可以通过这个指针来调用这个函数。 C语言可以将函数名作为一个函数的参数传递给另一个函数,相当于将函数名赋给形参。 在被调用函数中,接受函数名的形参是指向函数的指针。
返回指针的函数 C语言函数的返回值,可以是除了数组和函数之外的任何类型和指向任何类型的指针。 返回指针的函数的定义: 类型标识符 *函数名(参数列表); 例如: Int *a(int x,int y); 它表示函数a是一个返回指针指向int型的指针的函数。 见【例8-43】
【例8-43】 #include<stdio.h> #include<string.h> char *maxstr(char *str1,char *str2) { if(strcmp(str1,str2)>=0) return str1; else return str2; } void main() char string1[10],string2[10],*result; scanf("%s %s",string1,string2); result=maxstr(string1,string2); printf("The max string is %s\n",result); 【例8-43】 运行结果: a1234 b1234 The max string is b1234