运行结果是:编译通过,但是有逻辑错误。逻辑错误是这个函数一点作用都没起到,两个数完全没有交换。后来学到指针,我才明白。原来函数的执行,是把实参中的数据拷贝到形参中,就像复制了一份,传过去的是复制品,也就是大家所说的单向的值传递。再函数里可以对值进行应用,但是对值的操作一点都不会影响到实参值。那该怎样写这个交换函数呢?刚学指针不久我写了以下代码:
这里已经运用了指针,按说已经可以将两个数交换了,但是运行结果同上一次的一样,完全看不到任何作用。后来在爱机器人网上跟大家交流的时候弄明白了这个问题。如果形参时指针,从实参到形参的传递是单向的地址传递,也是先把地址复制一份,然后将复制品传递过去,对复制品的操作不能对实参产生任何影响,即使产生了影响(那得用二级指针了,后面会明白的),也只是将a、b的地址交换了一下,a、b的值依然不变。那要怎么样实现交换的函数呢?这里就可以看出间接访问的优越性了。虽然不能对实参造成影响,我们是可以应用的传递来的值的。于是有了以下代码:
void change(int *x,int *y)
这样就完全实现了交换函数。在函数内,我们虽然得到的是实参的复制品,但是我们可以利用这个复制品的数据(也就是地址)。我们已经知道了a、b的地址,自然就可以对a、b的值进行操作了。首先用*取到地址中存放的内容,然后将他们交换。这里直接对内存操作,交换的目的可以轻松达到。
疑问一、我们最常用的printf()函数的第一个参数到底是什么呢?为什么我们可以用"abc..."放在里面?
疑问二、定义
void str_copy(char *to, char *from)
{
}
大家可以看到在这一行*to =*from;其实是分别将from字符数据复制给to。大家可以想一想第一次执行循环的时候,就是将'a'赋值给'\0',这里的'a'和'\0'是什么,是代码区的内容,就跟常量123一样,我们在自己写代码改变自己代码的内容,这当然会报错,C语言中是不允许这样的。所以对""的理解还要加上一条:4、引起来的内容是存在代码区的常量。所以说要先把字符串中的数据用字符变量数组保存起来,然后传去变量的指针,就可以实现了,所以这个函数的用法应该是:
char a[] = "asdasd",b[] = "";
strcpy(b,a);
void str_copy(char **to, char **from)
{
}
void main()
{
}
结果输出结果和想想中的一样:
asdasdasd
asdasdasd
一点小激动后就想测试变量的指针通不通行:
void str_copy(char **to, char **from)
{
}
void main()
{
}
结果编译报错: cannot convert parameter 1 from 'char (*)[1]' to 'char**
也就是说:不能把char (*)[1]型的参数赋值给 char **型的。
问题出在传参这一步,为什么会这样呢?这个问题比较难缠,后来查了《C和指针》一书才弄明白:
1、指针中存的不光是内存地址,还有数据类型用来控制分配多少空间。
2、数组名和指针的差别: 例如 int a[5]
a的特点有:
1、开辟了5个连续的内存空间。
2、每个内存空间都是占四个字节的int型
3、把这写空间分配到适当的位置,并有a来指向第一个数据
1、开辟了占四个字节的空间。
2、具体这个空间在哪里不知道,很可能就是一个野指针。
3、b后面没有继续开辟存放用的空间。
明白了这些以后再来看我们的问题。其实char a[] ="asdasdasd";后&a应该是一个指向数组的指针,而不是指向指针的指针,所以不能赋值给形参char **from。数组名与指针差别并不很大,那为什么这里不能赋值呢?
再来回顾一个问题 形参 charp[]这样的是不用之名p的长度的,因为传来的实参一定能说明这个长度。但是它必须指明这个指针是指向char行的,因为要计算字节来分配空间。同理chara[] ="asdasdasd";后的&a指向的内容并不是一个简单指针,因为他包含了有10个字符这样用来计算分配多少字节的数据,而char**from指向的内容就是一个简单的指针,所以他俩很不一样,不能相互赋值。那怎么样修复呢?把参数改为:
void str_copy(char **to, char (*from)[10])
char
后面就不用看了,肯定行不通,因为数组名不能拿来做运算。
转自:http://blog.sina.com.cn/s/blog_9da24f3b01013199.html