一.指向字符串的指针
定义一个字符型指针,该指针是字符串的首地址(字符串是字符数组),定义格式为:
char *p; //未初始化
char *p = "Program"; //初始化
输出一个字符串,可以有以下几个办法:
法一:使用数组名输出字符串
#include<stdio.h>
int main()
{
char str[] = "Program!";
printf("%s\n",str);
return 0;
}
法二:使用指针输出字符串
#include<stdio.h>
int main()
{
char *str;
str = "Program!";
printf("%s",str);
return 0;
}
字符指针和字符数组之间的区别:
char *str = "Programming";
char a[] = "Programming";
1.str是指针变量,可多次赋值,a是数组名表示地址常量,不能复制,且a不能再次赋值,已经预先分配存储单元。字符串变量本身是一个变量,用于存放字符串的首地址。字符串本身是存放一块连续内存空间并以"\0"作为结束的数据。
2. 对于指针变量,可以使用char *p; p = "Programming"; ,但字符数组不能写成:
char a[20]; a = {"Programming"}; 必须逐一对字符赋值。
二.指针与函数
1.指针变量作为函数参数
C语言调用函数,实参传递给形参是采用值传递的方式。函数对参数的修改结果不会待会主调函数。但编写程序时,函数常需要将多个变量的修改结果返回到主调函数(return只能返回一个值)。如果用指针变量作为形参,就可以将地址的值传递实现指向变量的引用传递。数据传递有以下几种方法:
(1).实参与形参之间的数据传递
(2).被调函数通过return语句把函数值返回到主调函数
(3).通过全局变量交换数据
(4).利用指针型参数在主调函数和被调函数之间传递参数
指针变量作为函数参数是一种地址传递的方式。它的特点:共享内存,"双向"传递。
例如:交换两变量值:
void swap(int x,int y)
{
int temp;
temp=x;
x = y;
y = temp;
}
int main()
{
int a = 10, b= 20;
swap(a,b);
printf("\n%d,%d\n",a,b);
return 0;
}
执行后会发现a和b的值没有变化,因为函数内部x和y的值被交换,再函数结束后局部变量x和y被消除,a和b的值没有变化,正确写法如下:
#include<stdio.h>
void swap(int *p1, int *p2)
{
int temp;
temp = *p1; //把p1指针的数据传给temp
*p1 = *p2; //p1指针的数据等于p2指针的数据
*p2 = temp; //p2指针的数据等于交换前p1指针的数据
}
int main()
{
int a=10,b=20;
swap(a,b)
printf("%d,%d",a,b)
return 0;
}
2.指向函数指针变量
在C语言中,一个函数占用一端连续的内存区,且函数名具有与数组名类似的性质,数组名代表数组首地址,函数名代表函数的起始地址(该函数程序代码段在内存中所占用的存储空间的首地址,也称为函数入口地址)。不同的函数有不同的函数地址,编译器通过函数名来索引函数入口地址。
为了方便操作相同的函数,C语言引进了函数指针(function pointer)。可以把函数的这个首地址(入口地址)赋予一个指针变量,使该指针变量指向该函数。然后通过指针变量就可以找到这个函数,我们把这个指针变量成为“函数指针变量”。
定义形式为:
数据类型名 (*函数指针名)();
例如: int (*pf)();
函数的指针是函数代码入口的变量,本身不提供独立的函数代码。访问函数指针之前需要初始化,函数名代表函数代码的入口地址。
函数指针初始化的形式有两种:一为直接赋值,二是加取地址运算符"&"赋值。格式为:
函数指针名 = 函数名;
函数指针名 = &函数名;
也可以在定义时进行初始化:
数据类型名 (*函数指针名)() = &函数名;
数据类型名 (*函数指针名)()= 函数名;
函数指针与变量指针的共同之处都是可以间接访问。函数指针指向内存的程序代码存储区,通过间接存取运算使程序流程转移到指针所指向的函数入口,取出函数的机器指令并执行函数,完成函数的调用。
通过函数指针调用函数的一般形式为:
(*函数指针变量名)(实参表);
注意:由于优先度不同,*函数指针变量名必须用括号括起来,表示间接调用指针变量所指向的函数;右侧括号中的内容为传递到被调函数的实参表。
例如:
#include<stdio.h>
int main()
{
int max(),a,b,c;
int (*p)();
p = max;
scanf("%d,%d",&a,&b);
c = (*p)(a,b);
printf("max=%d",c);
return 0;
}
int max(int x,int y)
{
if(x>y)
return x;
else
return y;
}
3.返回指针值的函数
在C语言中,允许函数返回值的类型为指针,这种返回指针值的函数称为指针型函数。一般形式为:
数据类型 *函数名(参数表);
例如: double *fa(int x,double y);
函数名前的"*"表示函数的返回值是一个指针,“数据类型名”是指针所指变量的类型。
注意:
1. 指针函数中的return的返回值必须是与函数类型一致的指针;
2.返回值必须是外部或静态存储类别的变量指针或数组指针,以保证主调函数能正确使用数据。
3.不要把返回指针函数说明与指向函数的指针变量混淆,int (*func)()和int *func()含义不同
例如:
#include <stdio.h>
char *month_name(int n);
int main()
{
int n;
char *p;
printf("输出一个月份的数字\n");
scanf("%d",&n);
p = month_name(n);
printf("%s",p);
return 0;
}
char *month_name(int n)
{
static char *name[] = {"非法数据","一月","二月","三月","四月","五月","六月","七月","八月",
"九月","十月","十一月","十二月"};
if(n<1||n>12)
return name[0];
else
return name[n];
}
#include <stdio.h>
char *match(char c,char *s)
{
while(*s!="\0")
if(*s==c)
return s; //返回指针
else
s++; //指针下移
return 0;
}
int main()
{
char *cp = "ABCDEFGHIJK";
printf("%s\n",match('B',cp));
}