正文
c语言函数指针何时使用 c函数指针的用法
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
什么时候需要用到指针?
主要要用到的地方是函数。
当你需要把函数(子程序)运行结果通过参数带回主程序(或调用这个函数的某程序块),必须用指针。
有许多系统函数和库函数,原型定义用了指针做参数,你运用这些函数时,实参须与它们对应,要用指针。
输入语句中的参数,要用指针,例如 scanf中的参数。
第二个主要要用到的地方是动态数组声明。
例如一维动态数组可以声明成一个指针,当需要时动态分配单元,用毕,释放分配了的单元。
float *a; // 声明成一个指针
...
a = (float *) malloc( 200000 * sizeof(float)); // 需要时动态分配
...
for (i=0;i200000;i++) { ...a[i]....}; // 使用
...
free(a); // 用毕释放
第三,其它。好像不多啦
c语言指针怎么理解,什么时候会用到指针,要注意哪些方面
cpu自己有运算器和寄存器c语言函数指针何时使用,通过总线与存储器件相连c语言函数指针何时使用,在执行运算时c语言函数指针何时使用,
需要将数据冲存储器件上面将参与运算的数据读入,运算完成后再送出到
存储区。那么cpu读入时需要访问存储器件的某个单元,需要指定这个单元
的编号,我们管这个编号叫存储地址。
比如:int a[10],*p; p=a[3];a就是一个拥有10个整型数据的数据区
的首地址,变量p是存放地址的,称为指针型变量,赋值时需要取相应存储
区的地址,p=a[3];就是取数组a的第4个单元的地址给p,那么p就拿到了
这个单元的地址,*p=5;就相当于a[3]=5;的操作,p++;后p指针就指向a[4]。
在操作大块数据时,一般记录首地址(数组指针),然后根据首地址再加
上偏移量来访问整个数据,在c语言函数指针何时使用你程序中写a[3]时,计算机就会取a数组对应
的首地址再加3个整型偏移量来访问相应数据。用指针p访问a数组的好处
是,不用每次计算a加多少偏移访问数据,而是使p指向某数据后可以p++
或p--来访问前一个或后一个数据。
注意:
1.指针存放地址用,不是存储实际数据的,它是用来找数的,在
程序中要注意这点,往往出问题的是,指针还没有赋值就用来操作,或
用指针来存放数据,如:int *p=15,s[10]={ 0,15,{0} };的
p指针赋值有问题,这样计算机会把15当成地址存放到p变量中,以后用
*p访问得到的数据就不是你想要的数据了。(应该类似:p=s+1; *p=15;)
2.指针访问数据区一般需要程序来控制不要越界,比如定义了10个单元
的数据区,你不能让指针超出这10个单元的范围,否则得到的数据就是
不靠谱的。
3.指针的定义只是开设了可以访问数据区或数组的变量,数据区和数组
需要你的程序另行开设,然后把数据区或数组的某个单元的地址赋值给
指针变量,不要认定义了能访问数组的指针,数组就定义好了。
4.指针存放的地址最好不要用来与其他地址比较,除非你能确认地址比
较的结果肯定是你想要的。
5.举例来说,int a[10],*p=a;中a和p都是指针(地址),但a和p是不同的
在编译器眼中,a是一个数据区的首地址,是一个标记,你程序中使用a
时,编译器会知道用数据区的首地址来替换操作,而p是你自己程序开
设的变量,可以在程序中操作比如p++; p=a;等,但作为记号的a就不能
在程序中操作了,如a++; a=p;就是错的了。
6.子程序如果参数是指针型的,这个参数由子程序开设的指针型临时
变量存储,这个临时变量可以进行操作,但不会返回给调用者的指针型
变量。
如:int a[10],*p; int f(int *s) { s++; } main() { p=a; f(p); }
s再怎么加减都不会影响p。
C语言中函数指针用法
函数在内存中有一个物理位置,而这个位置是可以赋给一个指针的。一零点函数的地址就是该函数的入口点。因此,函数指针可被用来调用一个函数。函数的地址是用不带任何括号或参数的函数名来得到的。(这很类似于数组地址的得到方法,即,在只有数组名而无下标是就得到数组地址。)
怎样说明一个函数指针变量呢 ?
为了说明一个变量 fn_pointer 的类型是"返回值为 int 的函数指针", 你可以使用下面的说明语句c语言函数指针何时使用:
int (*fn_pointer) ()c语言函数指针何时使用;
为了让编译器能正确地解释这句语句, *fn_pointer 必须用括号围起来。若漏了这对括号, 则:
int *fn_pointer ();
的意思完全不同了。fn_pointer 将是一个函数名, 其返回值为 int 类型的指针。
2:函数指针变量
在C语言中规定,一个函数总是占用一段连续的内存区, 而函数名就是该函数所占内存区的首地址。 我们可以把函数的这个首地址 ( 或称入口地址 ) 赋予一个指针变量, 使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。我们把这种指向函数的指针变量称为 " 函数指针变量 " 。
函数指针变量定义的一般形式为:
类型说明符 (* 指针变量名 )();
其中 " 类型说明符 " 表示被指函数的返回值的类型。 "(* 指针变量名 )" 表示 "*" 后面的变量是定义的指针变量。 最后的空括号表示指针变量所指的是一个函数。
例如: int (*pf)();
表示 pf 是一个指向函数入口的指针变量,该函数的返回值 ( 函数值 ) 是整型。
下面通过例子来说明用指针形式实现对函数调用的方法。
int max(int a,int b)
{
if(ab)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);
}
从上述程序可以看出用,函数指针变量形式调用函数的步骤如下:
1. 先定义函数指针变量,如后一程序中第 9 行 int (*pmax)(); 定义 pmax 为函数指针变量。
2. 把被调函数的入口地址 ( 函数名 ) 赋予该函数指针变量,如程序中第 11 行 pmax=max;
3. 用函数指针变量形式调用函数,如程序第 14 行 z=(*pmax)(x,y); 调用函数的一般形式为: (* 指针变量名 ) ( 实参表 ) 使用函数指针变量还应注意以下两点:
a. 函数指针变量不能进行算术运算,这是与数组指针变量不同的。数组指针变量加减一个整数可使指针移动指向后面或前面的数组元素,而函数指针的移动是毫无意义的。
b. 函数调用中 "(* 指针变量名 )" 的两边的括号不可少,其中的 * 不应该理解为求值运算,在此处它只是一种表示符号。
3:指针型函数
前面我们介绍过,所谓函数类型是指函数返回值的类型。 在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 行是个条件语句,其语义是,如输入为负数 (i0) 则中止程序运行退出程序。 exit 是一个库函数, exit(1) 表示发生错误后退出程序, exit(0) 表示正常退出。
应该特别注意的是函数指针变量和指针型函数这两者在写法和意义上的区别。如 int(*p)() 和 int *p() 是两个完全不同的量。 int(*p)() 是一个变量说明,说明 p 是一个指向函数入口的指针变量,该函数的返回值是整型量, (*p) 的两边的括号不能少。
int *p() 则不是变量说明而是函数说明,说明 p 是一个指针型函数,其返回值是一个指向整型量的指针,*p 两边没有括号。作为函数说明, 在括号内最好写入形式参数,这样便于与变量说明区别。 对于指针型函数定义,int *p() 只是函数头部分,一般还应该有函数体部分。
main()
{
int i;
char *day_name(int n);
printf("input Day No:/n");
scanf("%d",i);
if(i0) exit(1);
printf("Day No:%2d--%s/n",i,day_name(i));
}
char *day_n
ame(int n)
{
static char *name[]={ "Illegal day",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"};
return((n1||n7) ? name[0] : name[n]);
}
本程序是通过指针函数,输入一个 1 ~ 7 之间的整数, 输出对应的星期名。指针数组的说明与使用一个数组的元素值为指针则是指针数组。指针数组是一组有序的指针的集合。指针数组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量。
指针数组说明的一般形式为: 类型说明符 * 数组名 [ 数组长度 ]
其中类型说明符为指针值所指向的变量的类型。例如: int *pa[3] 表示 pa 是一个指针数组,它有三个数组元素, 每个元素值都是一个指针,指向整型变量。通常可用一个指针数组来指向一个二维数组。 指针数组中的每个元素被赋予二维数组每一行的首地址,因此也可理解为指向一个一维数组。图 6—6 表示了这种关系。
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];
main()
{
int i;
for(i=0;i3;i++)
printf("%d,%d,%d/n",a[i][2-i],*a[i],*(*(a+i)+i));
for(i=0;i3;i++)
printf("%d,%d,%d/n",*pa[i],p[i],*(p+i));
}
本例程序中, pa 是一个指针数组,三个元素分别指向二维数组 a 的各行。然后用循环语句输出指定的数组元素。其中 *a[i] 表示 i 行 0 列元素值; *(*(a+i)+i) 表示 i 行 i 列的元素值; *pa[i] 表示 i 行 0 列元素值;由于 p 与 a[0] 相同,故 p[i] 表示 0 行 i 列的值; *(p+i) 表示 0 行 i 列的值。读者可仔细领会元素值的各种不同的表示方法。 应该注意指针数组和二维数组指针变量的区别。 这两者虽然都可用来表示二维数组,但是其表示方法和意义是不同的
这个C语言代码中为什么不用指针?指针究竟什么时候用?
一般来说不涉及动态分配大小c语言函数指针何时使用,不涉及在函数中更改实参(比如自己实现两个int交换c语言函数指针何时使用的swap 主法这类)c语言函数指针何时使用,就不需要用指针。
c语言什么时候使用数组,什么时候使用指针?
任何时候都可以使用数组,使用指针。
定义时,通常只有字符指针,和字符数组指针直接定义。用来表示字符串或字符串数组。
其他一般定义数组。操作时用指针或数组。
其他指针,多半用在参数传递,数据结构内部(不确定需要内存的大小,或者链表,二叉树等链式结构)的时候。
还有一种是有些函数参数就是指针,这时定义一个指针,来操作传进来的指针参数比较好。
指针作为参数,有一下几种用法,
1)当作数组用,用来获取或设置数组元素。
2)把一个比较长的数据结构传入函数,只需要一个指针就够了。
3)传入变量的地址,用来读取或修改变量的值,主要是为了修改用。
直接定义一个不指向任何对象的指针,并且也从不给他赋值,没什么意义;
指针要么指向数组,要么指向变量,要么动态申请内存。
NULL指针,只是一个方便的指针,表示不指向任何对象。
真正有用的还是指向具体对象的指针。
如果定义了一个指针,使用时要让他指向一个具体对象,当需要他不指向什么对象的时候,给他赋值为NULL;
PS:
C语言,数组名只是一个指针常量而已,离开定义可见处,数组大小的信息就不存在了。
只有定义完全可见的地方,才可以获得数组的大小。
数组作为函数的参数,和外部引用声明都不能获得数组的大小。
参数只能传递指针,参数的大小只是指针的大小;
只能看到声明的地方,获取数组大小的努力,只能换来错误。
void fun1(int a[10]) //== void fun1(int a[]) ==void fun1(int *a)
{
}
void fun2(int [10][10])// ==void fun2(int a[][10])== void fun2(int (*a)[10])
{
}
c语言函数指针何时使用的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于c函数指针的用法、c语言函数指针何时使用的信息别忘了在本站进行查找喔。