c语言指针。调用完函数后(main函数外面的函数)函数里面的指针消失了吗?没有

查看:11986|回复:2
提示: 作者被禁止或删除 内容自动屏蔽
  指针函数是指带指针的函数,即本质是一个函数。
  我们知道函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。其定义格式如下所示:
  返回类型标识符 *返回名称(形式参数表)
  { 函数体 }
  返回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。例如下面一个返回指针函数的例子:
  #include
  float *find();
  main()
  static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}};
  float *p;
  int i,m;
  printf(&Enter the number to be found:&);
  scanf(&%d&,&m);
  printf(&the score of NO.%d are:\n&,m);
  p=find(score,m);
  for(i=0;i&4;i++)
  printf(&%5.2f\t&,*(p+i));
  float *find(float(*pionter)[4],int n)/*定义指针函数*/
  float *
  pt=*(pionter+n);
  return(pt);
  学生学号从0号算起,函数find()被定义为指针函数,起形参pointer是指针指向包含4个元素的一维数组的指针变量。pointer+1指向score的第一行。*(pointer+1)指向第一行的第0个元素。pt是一个指针变量,它指向浮点型变量。main()函数中调用find()函数,将score数组的首地址传给pointer.
  【注意】
  指针函数不同于函数指针, int (*f)(int a);或者char (*f1)(void);
  函数指针声明为指针,它与变量指针不同之处是,它不是指向变量,而是指向函数。
  函数指针有两个用途:调用函数和做函数的参数.
指向函数的指针:指向函数的指针变量
来源: 发布时间:星期四, 日 浏览:108次 评论:0
函数的指针是指函数的入口地址,和数组名代表数组的首地址一样,函数名代表函数的入口地址。
若有一个指针变量,存放某一个函数的入口地址,我们可以通过指向这个函数的指针变量来调用函数。
1.定义指向函数的指针变量
形式如下:
类型标识符(*变量标识符)();
类型标识符是指针变量所指向的函数类型,变量标识符是指向函数的指针变量名。
int(*p)();
定义了一个指向函数的指针变量p,它可以存放一类整型函数的入口地址,程序中把哪一个函数的入口地址赋给它,它就指向哪一个函数。
(1)定义指向函数的指针变量,可以指向一类函数。
(2)定义指向函数的指针变量时,括号不能省略。
形式int*p()定义的是指针函数头,返回值是指向整型数据的指针值,而不是指向函数的指针变量。
(3)对指向函数的指针变量p,p+i、p++、p--等运算无意义。
2.让指针变量指向函数
定义了指向函数的指针变量,就可以在指针变量与特定函数之间建立关联,让指针变量指向特定函数。
建立关联的方法为:
指针变量一函数名;
(1)指针变量只能指向定义时所指定的一类函数。
(2)一个指针变量可以先后指向多个不同的函数。
3.利用指针实现函数调用
指针变量一旦指向某函数,利用指针所指向的变量可以实现函数调用。
一般形式:
(*指针变量)(实参表);简单的C语言如程序,想要把文件指针写如函数里。main函数是当输 - 爱问知识人
(window.slotbydup=window.slotbydup || []).push({
id: '2491531',
container: s,
size: '150,90',
display: 'inlay-fix'
简单的C语言
,想要把文件指针写如函数里。main函数是当输入“2”时运行函数fun,也就是仅仅的想输入东西。请问,函数(也就是这个以文件指针作为的函数) 外面的返回值是什么类型,里面形参类型是什么。并且如果把函数改为读取文件内容“read”时,返回类型和形参类型是什么?住函数是否要加变量。最好详细点,谢谢。
#include &stdio.h&
void fun()
{
char ch='a';
if ((f=fopen("c:\\aa.dat","w"))==NULL)
printf("File Can't be find!\n");
while (ch!='\n')
ch=getchar();
fputc(ch,f);
fclose(f);
void main()
{
printf("请输入:\n");
scanf("%d",&a);
case 1:printf("OK\n");
case 2: fun();
回答LZ的问题:
以该程序为例,函数fun 的返回类型说明符为 void,表示它的返回为“空类型”,也就是无返回值的意思。
而且该函数也没有形参,因为fun(),括号里为空,没有参数。文件的打开方式与函数的形参或实参没有直接关系。 实参是实际调用时的参数,形参是接受实参值的形式参数,是根据函数设计的需求来定的。
在本例中,如果将文件打开方式改为"r"读文件,那么需要修改该函数体,将文件内容显示出来,而不能使用fputc这样的写文件函数了。
下面的注释,仅供参考:
#include &stdio.h&
//包含头文件
void fun()
//函数头,void 表示无返回值 没有形参
//定义文件指针
char ch='a';
//定义char型变量ch,初始值为'a'
if ((f=fopen("c:\\aa.dat","w"))==NULL)
//用fopen函数打开C根目录下的aa.dat文件,以"w"写方式,并且让f文件指针指向该文件,如果fopen函数返回值等于NULL,则提示并结束程序.
回答LZ的问题:
以该程序为例,函数fun 的返回类型说明符为 void,表示它的返回为“空类型”,也就是无返回值的意思。
而且该函数也没有形参,因为fun(),括号里为空,没有参数。文件的打开方式与函数的形参或实参没有直接关系。 实参是实际调用时的参数,形参是接受实参值的形式参数,是根据函数设计的需求来定的。
在本例中,如果将文件打开方式改为"r"读文件,那么需要修改该函数体,将文件内容显示出来,而不能使用fputc这样的写文件函数了。
下面的注释,仅供参考:
#include &stdio.h&
//包含头文件
void fun()
//函数头,void 表示无返回值 没有形参
//定义文件指针
char ch='a';
//定义char型变量ch,初始值为'a'
if ((f=fopen("c:\\aa.dat","w"))==NULL)
//用fopen函数打开C根目录下的aa.dat文件,以"w"写方式,并且让f文件指针指向该文件,如果fopen函数返回值等于NULL,则提示并结束程序.
printf("File Can't be find!\n");
//提示文件打开失败
else //文件打开成功
while (ch!='\n')
//while循环,循环终止条件是当ch变量等于'\n'时
ch=getchar();
//得到键盘输入的字符
fputc(ch,f);
//将字符写入f指针所指向的文件
fclose(f);
//结束循环,关闭文件
void main()
//定义int型变量a,初始化为0值
printf("请输入:\n");
//提示输入信息
scanf("%d",&a);
//从键盘输入,赋值给a变量
//多路分支判断
case 1:printf("OK\n");
//如果输入1,打印OK后退出
case 2: fun();
//如果输入2,调用fun函数后退出
在键盘输入2,程序调用fun函数,是由switch多路判断语句来控制实现的。至于 fun 函数的返回值和形参类型写什么,与是否调用函数fun没有关系。
至于函数要不要返回值,看实际问题的需要了,如果需要在主调函数中处理或显示函数处理的结果,那么就需要设置恰当的返回值类型。至于形参,则要看设计函数的实际需求。
建议LZ,参阅相关资料关于 switch 语句的使用方法,及有函数返回值及形参的具体例子。
现在的程序代码,在运行时,输入2,就已经调用fun函数了,没有问题。只是代码控制逻辑上有点问题。输入2之后不能回车,否则就退出了。应该输入2之后,接着输入其它字符。回车结束,生成aa.dat文件!
java方法重载
在判断输入的逻辑上还有些问题,之所以出现需要多输入一个回车的原因是你的WHILE判断中调用了两次getchar(),也就是说,如果第一次调用getchar()不...
函数旁边的意思是:
1. 区分变量于函数.函数的旁边没有括号.
2. 括号内可以是空白, 也可有一个或多个变量或Pointer. 把主程序的数据送到函数里边...
是这样的,因为p=&a,所以*p和a已经公用一块地址空间了,换句话说此时,a就是*p,*p就是a,当*p = *p + 50;,看起来跟a没有什么关系,但是a已...
#include &stdio.h&
void reverse(char *line){
大家还关注
C语言运行错误 输入5个数,把5个数按从...C语言函数指针基础 - 文章 - 伯乐在线
& C语言函数指针基础
本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础。如果你不讨厌事无巨细,请尽情阅读吧。
函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具。本文将从C语言函数指针的基础开始介绍,再结合一些简单的用法和关于函数名称和地址的趣闻。在最后,本文给出一种简单的方式来看待函数指针,让你对其用法有一个更清晰的理解。
函数指针和一个简单的函数
我们从一个非常简单的”Hello World“函数入手,来见识一下怎样创建一个函数指针。
#include &stdio.h&
// 函数原型
void sayHello();
//函数实现
void sayHello(){
printf("hello world\n");
// main函数调用
int main() {
sayHello();
1234567891011121314
#include &stdio.h&&// 函数原型void sayHello();&//函数实现void sayHello(){&&&&printf("hello world\n");}&// main函数调用int main() {&&&&sayHello();}
我们定义了一个名为sayHello的函数,它没有返回值也不接受任何参数。当我们在main函数中调用它的时候,它向屏幕输出出”hello world“。非常简单。接下来,我们改写一下main函数,之前直接调用的sayHello函数,现在改用函数指针来调用它。
int main() {
void (*sayHelloPtr)() = sayH
(*sayHelloPtr)();
int main() {&&&&void (*sayHelloPtr)() = sayHello;&&&&(*sayHelloPtr)();}
第二行void (*sayHelloPtr)()的语法看起来有些奇怪,我们来一步一步分析。
这里,关键字void的作用是说我们创建了一个函数指针,并让它指向了一个返回void(也就是没有返回值)的函数。
就像其他任何指针都必须有一个名称一样,这里sayHelloPtr被当作这个函数指针的名称。
我们用*符号来表示这是一个指针,这跟声明一个指向整数或者字符的指针没有任何区别。
*sayHelloPtr两端的括号是必须的,否则,上述声明变成void *sayHelloPtr(),*会优先跟void结合,变成了一个返回指向void的指针的普通函数的声明。因此,函数指针声明的时候不要忘记加上括号,这非常关键。
参数列表紧跟在指针名之后,这个例子中由于没有参数,所以是一对空括号()。
将上述要点结合起来,void (*syaHelloPtr)()的意义就非常清楚了,这是一个函数指针,它指向一个不接收参数且没有返回值的函数。
在上面的第二行代码,即void (*sayHelloPtr)() = sayH,我们将sayHello这个函数名赋给了我们新建的函数指针。关于函数名的更多细节我们会在下文中讨论,现在暂时可以将其看作一个标签,它代表函数的地址,并且可以赋值给函数指针。这就跟语句int *x = &中我们把myint的地址赋给一个指向整数的指针一样。只是当我们考虑函数的时候,我们不需要加上一个取地址符&。简而言之,函数名就是它的地址。接着看第三行,我们用代码’(*sayHelloPtr)();·‘解引用并调用了函数指针。
在第二行被声明之后,sayHelloPtr作为函数指针的名称,跟其他任何指针没有差别,能够储值和赋值。
我们对sayHelloPtr解引用的方式也与其他任何指针一样,即在指针之前使用解引用符*,也就是代码中的*sayHelloPtr。
同样的,我们需要在其两端加上括号,即(*sayHelloPtr),否则它就不被当做一个函数指针。因此,记得声明和解引用的时候都要在两端加上括号。
括号操作符用于C语言中的函数调用,如果有参数参与,就将其放入括号中。这对于函数指针也是相似的,即代码中的(*sayHelloPtr)()。
这个函数没有返回值,也就没有必要将它赋值给任何变量。单独来说,这个调用跟sayHello()没什么两样。
接下来,我们再对函数稍加修改。你会看到函数指针奇怪的语法,以及用调用普通函数的方法来调用赋值后函数指针的现象。
int main() {
void (*sayHelloPtr)() = sayH
sayHelloPtr();
int main() {void (*sayHelloPtr)() = sayHello;sayHelloPtr();}
跟之前一样,我们将sayHello函数赋给函数指针。但是这一次,我们用调用普通函数的方法调用了它。稍后讨论函数名的时候我会解释这一现象,现在只需要知道(*syaHelloPtr)()和syaHelloPtr()是相同的即可。
带参数的函数指针
好了,这一次我们来创建一个新的函数指针吧。它指向的函数仍然不返回任何值,但有了参数。
#include &stdio.h&
//函数原型
void subtractAndPrint(int x, int y);
//函数实现
void subtractAndPrint(int x, int y) {
int z = x -
printf("Simon says, the answer is: %d\n", z);
//main函数调用
int main() {
void (*sapPtr)(int, int) = subtractAndP
(*sapPtr)(10, 2);
sapPtr(10, 2);
1234567891011121314151617
#include &stdio.h&&//函数原型void subtractAndPrint(int x, int y);&//函数实现void subtractAndPrint(int x, int y) {&&&&int z = x - y;&&&&printf("Simon says, the answer is: %d\n", z);}&//main函数调用int main() {&&&&void (*sapPtr)(int, int) = subtractAndPrint;&&&&(*sapPtr)(10, 2);&&&&sapPtr(10, 2);}
跟之前一样,代码包括函数原型,函数实现和在main函数中通过函数指针执行的语句。原型和实现中的特征标变了,之前的sayHello函数不接受任何参数,而这次的函数subtractAndPrint接受两个int作为参数。它将两个参数做一次减法,然后输出到屏幕上。
在第14行,我们通过'(*sapPtr)(int, int)’创建了sapPtr这个函数指针,与之前的区别仅仅是用(int, int)代替了原来的空括号。而这与新函数的特征标相符。
在第15行,解引用和执行函数的方式与之前完全相同,只是在括号中加入了两个参数,变成了(10, 2)。
在第16行,我们用调用普通函数的方法调用了函数指针。
带参数且有返回值的函数指针
这一次,我们把subtractAndPrint函数改成一个名为subtract的函数,让它把原本输出到屏幕上的结果作为返回值。
#include &stdio.h&
// 函数原型
int subtract(int x, int y);
// 函数实现
int subtract(int x, int y) {
return x -
// main函数调用
int main() {
int (*subtractPtr)(int, int) =
int y = (*subtractPtr)(10, 2);
printf("Subtract gives: %d\n", y);
int z = subtractPtr(10, 2);
printf("Subtract gives: %d\n", z);
1234567891011121314151617181920
#include &stdio.h&&// 函数原型int subtract(int x, int y);&// 函数实现int subtract(int x, int y) {&&&&return x - y;}&// main函数调用int main() {&&int (*subtractPtr)(int, int) = subtract;&&&int y = (*subtractPtr)(10, 2);&&printf("Subtract gives: %d\n", y);&&&int z = subtractPtr(10, 2);&&printf("Subtract gives: %d\n", z);}
这与subtractAndPrint函数非常相似,只是subtract函数返回了一个整数而已,特征标也理所当然的不一样了。
在第13行,我们通过int (*subtractPtr)(int, int)创建了subtractPtr这个函数指针。与上一个例子的区别只是把void换成了int来表示返回值。而这与subtract函数的特征标相符。
在在第15行,解引用和执行这个函数指针,除了将返回值赋值给了y以外,与调用subtractAndPrint没有任何区别。
在第16行,我们向屏幕输出了返回值。
18到19行,我们用调用普通函数的方法调用了函数指针,并且输出了结果。
这跟之前没什么两样,我们只是加上了返回值而已。接下来我们看看另一个稍微复杂点儿的例子——把函数指针作为参数传递给另一个函数。
把函数指针作为参数来传递
我们已经了解过了函数指针声明和执行的各种情况,不论它是否带参数,或者是否有返回值。接下来我们利用一个函数指针来根据不同的输入执行不同的函数。
#include &stdio.h&
// 函数原型
int add(int x, int y);
int subtract(int x, int y);
int domath(int (*mathop)(int, int), int x, int y);
// 加法 x+ y
int add(int x, init y) {
return x +
// 减法 x - y
int subtract(int x, int y) {
return x -
// 根据输入执行函数指针
int domath(int (*mathop)(int, int), int x, int y) {
return (*mathop)(x, y);
// main函数调用
int main() {
// 用加法调用domath
int a = domath(add, 10, 2);
printf("Add gives: %d\n", a);
// 用减法调用domath
int b = domath(subtract, 10, 2);
printf("Subtract gives: %d\n", b);
123456789101112131415161718192021222324252627282930313233
#include &stdio.h&&// 函数原型int add(int x, int y);int subtract(int x, int y);int domath(int (*mathop)(int, int), int x, int y);&// 加法 x+ yint add(int x, init y) {&&&&return x + y;}&// 减法 x - yint subtract(int x, int y) {&&&&return x - y;}&// 根据输入执行函数指针int domath(int (*mathop)(int, int), int x, int y) {&&&&return (*mathop)(x, y);}&// main函数调用int main() {&// 用加法调用domathint a = domath(add, 10, 2);printf("Add gives: %d\n", a);&// 用减法调用domathint b = domath(subtract, 10, 2);printf("Subtract gives: %d\n", b);}
我们来一步一步分析。
我们有两个特征标相同的函数,add和subtract,它们都返回一个整数并接受两个整数作为参数。
在第六行,我们定义了函数int domath(int (*mathop)(int, int), int x, int y)。它第一个参数int (*mathop)(int, int)是一个函数指针,指向返回一个整数并接受两个整数作为参数的函数。这就是我们之前见过的语法,没有任何不同。它的后两个整数参数则作为简单的输入。因此,这是一个接受一个函数指针和两个整数作为参数的函数。
19到21行,domath函数将自己的后两个整数参数传递给函数指针并调用它。当然,也可以像这么调用。mathop(x, y);
27到31行出现了我们没见过的代码。我们用函数名作为参数调用了domath函数。就像我之前说过的,函数名是函数的地址,而且能代替函数指针使用。
main函数调用了两次domath函数,一次用了add,一次用了subtract,并输出了这两次结果。
函数名和地址
既然有约在先,那我们就讨论一下函数名和地址作为结尾吧。一个函数名(或称标签),被转换成了一个指针本身。这表明在函数指针被要求当作输入的地方,就能够使用函数名。这也导致了一些看起来很糟糕的代码却能够正确的运行。瞧瞧下面这个例子。
#include &stdio.h&
// 函数原型
void add(char *name, int x, int y);
// 加法 x + y
void add(char *name, int x, int y) {
printf("%s gives: %d\n", name, x + y);
// main函数调用
int main() {
// 一些糟糕的函数指针赋值
void (*add1Ptr)(char*, int, int) =
void (*add2Ptr)(char*, int, int) = *
void (*add3Ptr)(char*, int, int) = &
void (*add4Ptr)(char*, int, int) = **
void (*add5Ptr)(char*, int, int) = ***
// 仍然能够正常运行
(*add1Ptr)("add1Ptr", 10, 2);
(*add2Ptr)("add2Ptr", 10, 2);
(*add3Ptr)("add3Ptr", 10, 2);
(*add4Ptr)("add4Ptr", 10, 2);
(*add5Ptr)("add5Ptr", 10, 2);
// 当然,这也能运行
add1Ptr("add1PtrFunc", 10, 2);
add2Ptr("add2PtrFunc", 10, 2);
add3Ptr("add3PtrFunc", 10, 2);
add4Ptr("add4PtrFunc", 10, 2);
add5Ptr("add5PtrFunc", 10, 2);
12345678910111213141516171819202122232425262728293031323334
#include &stdio.h&&// 函数原型void add(char *name, int x, int y);&// 加法 x + yvoid add(char *name, int x, int y) {&&&&printf("%s gives: %d\n", name, x + y);}&// main函数调用int main() {&&&&&// 一些糟糕的函数指针赋值&&&&void (*add1Ptr)(char*, int, int) = add;&&&&void (*add2Ptr)(char*, int, int) = *add;&&&&void (*add3Ptr)(char*, int, int) = &add;&&&&void (*add4Ptr)(char*, int, int) = **add;&&&&void (*add5Ptr)(char*, int, int) = ***add;&&&&&// 仍然能够正常运行&&&&(*add1Ptr)("add1Ptr", 10, 2);&&&&(*add2Ptr)("add2Ptr", 10, 2);&&&&(*add3Ptr)("add3Ptr", 10, 2);&&&&(*add4Ptr)("add4Ptr", 10, 2);&&&&(*add5Ptr)("add5Ptr", 10, 2);&&&&&// 当然,这也能运行&&&&add1Ptr("add1PtrFunc", 10, 2);&&&&add2Ptr("add2PtrFunc", 10, 2);&&&&add3Ptr("add3PtrFunc", 10, 2);&&&&add4Ptr("add4PtrFunc", 10, 2);&&&&add5Ptr("add5PtrFunc", 10, 2);}
这是一个简单的例子。运行这段代码,你会看到每个函数指针都会执行,只是会收到一些关于字符转换的警告。但是,这些函数指针都能正常工作。
在第15行,add作为函数名,返回这个函数的地址,它被隐式的转换为一个函数指针。我之前提到过,在函数指针被要求当作输入的地方,就能够使用函数名。
在第16行,解引用符作用于add之前,即*add,在返回在这个地址的函数。之后跟函数名一样,它被隐式的转换为一个函数指针。
在第17行,取地址符作用于add之前,即&add,返回这个函数的地址,之后又得到一个函数指针。
18到19行,add不断地解引用自身,不断返回函数名,并被转换为函数指针。到最后,它们的结果都和函数名没有区别。
显然,这段代码不是优秀的实例代码。我们从中收获到了如下知识:其一,函数名会被隐式的转换为函数指针,就像作为参数传递的时候,数组名被隐式的转换为指针一样。在函数指针被要求当作输入的任何地方,都能够使用函数名。其二,解引用符*和取地址符&用在函数名之前基本上都是多余的。
我希望本文帮助你们认清了函数指针以及它的用途。只要你掌握了函数指针,它就是C语言中一个强大的工具。我也许会在以后的文章中讲述更多函数指针的细节用法,包括回调和C语言中基本的面向对象等等。
我删掉了关于描述(*sayHelloPrt)(void)跟(*sayHelloPrt)()相同的那一部分,那其实是错误的。在评论区中,Dave G给出了一个关于这个问题很好的解释。
关于作者:
可能感兴趣的话题
此处讲的都是很基础但实用的函数指针,经常会遇到些人喜欢搞个 指向函数指针的指针,然后各种绕,以体现他的牛逼!
关于伯乐在线博客
在这个信息爆炸的时代,人们已然被大量、快速并且简短的信息所包围。然而,我们相信:过多“快餐”式的阅读只会令人“虚胖”,缺乏实质的内涵。伯乐在线内容团队正试图以我们微薄的力量,把优秀的原创文章和译文分享给读者,为“快餐”添加一些“营养”元素。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2016 伯乐在线共有 405 人关注过本帖
标题:关于指针在被传到被调用函数的问题(求助)
等 级:新手上路
结帖率:100%
&&已结贴√
&&问题点数:10&&回复次数:5&&&
关于指针在被传到被调用函数的问题(求助)
指针的这个问题我被困扰了很久,希望真正悟透的兄弟给上精确的答复,不要搜索或人去亦云的东西.为了能得到精确的答案,我干脆直接用下面这种方式提问:
书上说C语言是以传值的方式将参数值传递给被调用函数,被调用函数不能直接修改主调函数中变量的值.
下列程序中是主函数先调用第一个函数,然后在第一个函数里面又调用第二个函数.
问题1:在运行 exchange(p1, p2);后,被传到第一个函数的是指针变量p1,p2的(&&& )
A、指针指向的地址&&&&&B、所对应的变量a,b&&&&&& C、值5和6.
问题2:在第一个函数中又调用了第二个函数这时,这时被传到第二个函数中的是指针变量p1,p2的(&&& )
A、指针指向的地址&&&&&& B、所对应的变量a,b。&&& C、值5和6。程序代码:[color=#008000]/*交换a, b 两个数*/
#include &stdio.h&
void main()
&&& void exchange(int *q1, int *q2);
&&& int a ,&&&&&&&&&&&&&&&&&&&&&
&&& int *p1, *p2;
&&& a = <font color=#;
&&& b = <font color=#;
&&& p1 = &a;
&&& p2 = &b;
&&& exchange(p1, p2);
&&& printf(&\n%d %d\n&, a, b);&&&
&&& printf(&\n%d %d\n&, *p1, *p2);&&&&&&
void exchange(int *q1, int *q2)&&&//第一个函数
&&& void swap(int *qt1, int *qt2);
&&& if(*q1 & *q2)
&&&&&&&&swap(q1, q2);
void swap(int *qt1, int *qt2)&&& //第二个函数
&&& t = *qt1;
&&& *qt1 = *qt2;
&&& *qt2 =
搜索更多相关主题的帖子:
等 级:侠之大者
帖 子:140
专家分:470
楼主的提问方式估计大家很难接受哦!哈哈
不论是第一个函数还是第二个函数,本程序中传递的都是同一个内容,就是变量a和b所指的地址,这两个地址分别存储着变量
a和b的值,即5和6,其实你的函数中处理的就是变量a和b,
a--&xxxx1&&&&&&&&b--&xxxx2
&&& 5&&&&&&&&&&&&&&& 6
上面这个示意图xxxx表示的是内存地址
xxxx1 中存着变量a的值 -- 5
xxxx2 中存着变量b的值 -- 6
而传指针参数,就相当于把xxxx1和xxxx2 传进函数,所以当函数中对xxxx1和xxxx2进行赋值操作(写内存)时,
改变了xxxx1和xxxx2的内容,所以变量a和b的值也就被改动了,
呵呵,没有按照你的回答方式回答,请见谅!如果要是那样回答,我想你可能还是不明白是怎么回事的!
初学乍练,难免有错!
等 级:论坛游民
帖 子:49
专家分:65
你的答案都不标准,问题一答案传到第一个函数的是指针变量p1,p2的值,但它是a,b对应的地址!并不是5和6,也就是一个指针量;第二个答案也是一样的;两题你都应该加个选项D、所对应的变量a,b的存储地址!希望你能明白~
来 自:广东潮州
等 级:小飞侠
帖 子:1181
专家分:2784
回复 楼主 zpcg
一步一个脚印...............................默默地前进.....
诚邀乐于解答c菜鸟问题,的热心网友加入,&&QQ群
等 级:千里冰封
帖 子:1555
专家分:10000
楼主,类似的问题貌似问过的。“被调用函数不能直接修改主调函数中变量的值”,那就意味着可以间接修改,通过指针去修改。另外,楼主为了验证在被调函数中改变主调函数普通变量和指针变量的值,写了这两个测试函数,感觉有点绕。我另外写了swap_value和swap_pt,可以参考下。不对的地方可以讨论。
&&& 在调用函数里面改变主函数的数值,需要指向该变量的指针,因此,你要交换a,b的数值,需要传递&a,&b。因此你的 swap函数成功调换了a,b的数值;但是你要改变指针的值,那么同样需要指向指针的指针,因此需要有二级指针来完成。你用了1级指针当然达不到目 的了。
#include &stdio.h&
void main()
&&& void swap_pt(int **q1, int **q2);
&&& void swap_value(int *qt1, int *qt2);
&&& int a ,
&&& int *p1, *p2;
&&& scanf(&%d%d&, &a, &b);
&&& p1 = &a; p2 = &b;
&&& printf(&原来:\n&);
&&& printf(&p1=%p&&& p2=%p\n&, p1, p2);
&&& printf(&&a=%p&&& &b%p\n&, &a, &b);
&&& printf(&a=%d&&& b=%d\n&, a, b);
&&& swap_pt(&p1, &p2);
&&& printf(&\n\n交换指针后:\n&);
&&& printf(&p1=%p&&& p2=%p\n&, p1, p2);
&&& printf(&&a=%p&&& &b%p\n&, &a, &b);&&&
&&& printf(&a=%d&&& b=%d\n&, a, b);
&&& swap_value(&a, &b);
&&& printf(&\n\n交换数值后:\n&);
&&& printf(&p1=%p&&& p2=%p\n&, p1, p2);
&&& printf(&&a=%p&&& &b%p\n&, &a, &b);&&&
&&& printf(&a=%d&&& b=%d\n&, a, b);
void swap_pt(int **q1, int **q2)
void swap_value(int *qt1, int *qt2)
&&& t = *qt1;
&&& *qt1 = *qt2;
&&& *qt2 =
gcc编译后输出:
p1=0xbfb5fe1c&&& p2=0xbfb5fe18
&a=0xbfb5fe1c&&& &b0xbfb5fe18
a=12&&& b=45
交换指针后:
p1=0xbfb5fe18&&& p2=0xbfb5fe1c
&a=0xbfb5fe1c&&& &b0xbfb5fe18
a=12&&& b=45
交换数值后:
p1=0xbfb5fe18&&& p2=0xbfb5fe1c
&a=0xbfb5fe1c&&& &b0xbfb5fe18
a=45&&& b=12
[ 本帖最后由 pauljames 于
06:43 编辑 ]
经常不在线不能及时回复短消息,如有c/单片机/运动控制/数据采集等方面的项目难题可加qq。
等 级:论坛游民
帖 子:18
专家分:12
版权所有,并保留所有权利。
Powered by , Processed in 0.021355 second(s), 6 queries.
Copyright&, BCCN.NET, All Rights Reserved}

我要回帖

更多关于 c语言指针赋值 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信