指针与数组的关系

区别

若有定义int(*p)[3];则定义了一个名为p的指针变量,表示p是一个指针变量,它可以指向每行有三个整数(即int型)元素的二维数组.

p是指向一维数组的指针变量。
这句话的理解是首先(*p)[3]是一个指向一维数组的指针变量,意思就是p这个指针是指向一个含有3个元素的数组的,
那么p指针每一次加1就相当于把p中存的地址加6(前提是int类型占2个字节,在VC中是占4个字节)。
举个例子:int a[3][3]; int( *p)[3]; p =a; //p=a的意思是把数组a的首地址存放到p中
那么p[1]就是a[1][0]的地址,p[1][0]就等于a[1][0],而p[1][2]就等于a[1][2].


指针数组和指向数组的指针int *q[3],int(*p)[4]解析。
int a[3][4]; int(*p)[4]; int *q[3]; int(*p)[4]中的p是指向一维数组的指针变量,p可以赋值:
若p=a;则(p+i==&a[i])==(*(p+i)==a[i]), (*(p+i)+j==&a[i][j])==(*(*(p+i)+j)==a[i][j]);


int *q[3]中的q是一维指针数组的数组名,不是变量,不能赋值,如q=a是错误的,但是这个数组的
元素却是指针变量,就是说(q[3])整体是一个指针变量,可以赋值,如:q[i]=a[i]或者*(q+i)=a[i],但是q+i=&a[i]是错误的,还是
因为q不是变量,q+i是已经分配好的地址了。
各元素只有当它被赋值以后才能使用,例如 q[0]=a[0];q[1]=a[1];q[2]=a[2];这时这三个指针变量才有指向,
使用起来不会非法,*(q+i)+j=&a[i][j];  *(*(q+i)+j)=a[i][j]; 如果只用q[0]被赋值,当使用到*(q+1)+j
就是非法指向了。


指针数组说明的一般形式为:   类型说明符 * 数组名 [ 数组长度 ]   
其中类型说明符为指针值所指向的变量的类型。例如:  int *pa[3]  表示 pa 是一个指针数组,它有三个数组元素,  
每个元素值都是一个指针,指向整型变量。通常可用一个指针数组来指向一个二维数组。指针数组中的每个元素被赋予二维数组每一行的首地址,
因此也可理解为指向一个一维数组。   


/***********************************************************************
函数指针变量   
    在C语言中规定,一个函数总是占用一段连续的内存区,
而函数名就是该函数所占内存区的首地址。
我们可以把函数的这个首地址 ( 或称入口地址 ) 赋予一个指针变量,
使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。
我们把这种指向函数的指针变量称为 " 函数指针变量 " 。   
函数指针变量定义的一般形式为:   
类型说明符  (* 指针变量名 )();   
其中 " 类型说明符 " 表示被指函数的返回值的类型。
 "(*  指针变量名 )" 表示 "*" 后面的变量是定义的指针变量。   
 最后的空括号表示指针变量所指的是一个函数。   
例如:  int (*pf)();  
表示 pf 是一个指向函数入口的指针变量,该函数的返回值 ( 函数值 ) 是整型
 从下面程序可以看出用,函数指针变量形式调用函数的步骤如下:
1. 先定义函数指针变量,如后一程序中第 9 行  int (*pmax)(); 定义 pmax 为函数指针变量。   
2. 把被调函数的入口地址 ( 函数名 ) 赋予该函数指针变量,如程序中第 11 行  pmax=max;  
3. 用函数指针变量形式调用函数,如程序第 14 行  z=(*pmax)(x,y); 
调用函数的一般形式为: (* 指针变量名 ) ( 实参表 ) 使用函数指针变量还应注意以下两点:   
a. 函数指针变量不能进行算术运算,这是与数组指针变量不同的。
数组指针变量加减一个整数可使指针移动指向后面或前面的数组元素,
而函数指针的移动是毫无意义的。   
b. 函数调用中 "(* 指针变量名 )" 的两边的括号不可少,
其中的 * 不应该理解为求值运算,在此处它只是一种表示符号。
<span style="font-size:14px;">#include <stdio.h>
int max(int a,int b){  
if(a>b)return a;  
else return b;  
}  
main(){  
int max(int a,int b);  
int(*pmax)();  
int x,y,z;  
pmax=max;  
printf("input two numbers:\n");  
scanf("%d%d",&x,&y);  
z=(*pmax)(x,y);  
printf("maxmum=%d",z); 
getch(); 
} </span>






指针型函数   


前面我们介绍过,所谓函数类型是指函数返回值的类型。
在C语言中允许一个函数的返回值是一个指针 ( 即地址 ) ,
 这种返回指针值的函数称为指针型函数。   
定义指针型函数的一般形式为:    
类型说明符  * 函数名 ( 形参表 )   
{   
......  
}   
其中函数名之前加了 "*" 号表明这是一个指针型函数,即返回值是一个指针。
类型说明符表示了返回的指针值所指向的数据类型。   
如:   int *ap(int x,int y)  
{  
......  
}  
表示 ap 是一个返回指针值的指针型函数,它返回的指针指向一个整型变量。
下例中定义了一个指针型函数  day_name ,它的返回值指向一个字符串。
该函数中定义了一个静态指针数组 name 。 name  数组初始化赋值为八个字符串,
分别表示各个星期名及出错提示。形参 n 表示与星期名所对应的整数。在主函数中,
把输入的整数 i 作为实参,在 printf 语句中调用 day_name 函数并把 i 值传送给形参n。
 day_name 函数中的 return 语句包含一个条件表达式,  
 n 值若大于7或小于1则把 name[0]指针返回主函数输出出错提示字符串 "Illegal day"。
 否则返回主函数输出对应的星期名。主函数中的第 7 行是个条件语句,其语义是,
 如输入为负数 (i<0) 则中止程序运行退出程序。 exit 是一个库函数,
  exit(1) 表示发生错误后退出程序,  exit(0) 表示正常退出。   


应该特别注意的是函数指针变量和指针型函数这两者在写法和意义上的区别。
如 int(*p)() 和 int *p() 是两个完全不同的量。 int(*p)() 是一个变量说明,
说明 p  是一个指向函数入口的指针变量,该函数的返回值是整型量, 
(*p) 的两边的括号不能少。 int *p()  则不是变量说明而是函数说明,
说明 p 是一个指针型函数,其返回值是一个指向整型量的指针, 
*p 两边没有括号。作为函数说明,   在括号内最好写入形式参数,
这样便于与变量说明区别。   对于指针型函数定义, 
int *p() 只是函数头部分,一般还应该有函数体部分。
*******************************************************************************/ 
<span style="font-size:14px;">#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));  
getch();
}  
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]);  
}
</span>


在C语言程序设计中,无论规模多大的程序及复杂性如何,最终都要落实到每个小型函数的编写工作上。因此,C语言程序设计的基础工作是函数的设计和编号,掌握C语言函数的特点及函数调用时参数变化的情形,无疑是一个很重要的编程基本技术。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值