一·传值调用与传址调用
先看一个例子:
为什么前后输出的结果一样呢?
那是因为x,y作为形参,是实参的一份临时拷贝,但xy的地址和ab不同,所以改变xy的值对ab没影响。
即改变形参对实参没有影响。
那该如何解决呢?
那就需要用到传址调用。
将ab的地址传递给xy指针,这样对xy的操作实际就是对ab的改变。
总结(何时用传值何时传址):
1.传址调⽤,可以让函数和主调函数之间建⽴真正的联系,在函数内部可以修改主调函数中的变量;
2.未来函数中只是需要主调函数中的变量值来实现计算(如定义一个函数求xy的和),就可以采⽤传值调⽤。如果函数内部要修改主调函数中的变量的值,就需要传址调⽤。
二·数组名的理解
先区分几个概念:
1.一般来说:数组名就是首元素的地址 arr–>&arr[0]
但有两个特例:
(1)sizeof(arr)这里arr表示整个数组;
(2)&数组名,这里arr表示的是整个数组,取出的是整个数组的地址。
look
由此可见,arr与&arr[0]同
而且+1之后都跳过4个字节;
&arr输出的也是与前面一样的地址,
但&arr+1,跳过了40个字节,是一个数组的长度。
可以用指针来访问数组:
(一些等价代换)
三·指针传参的本质
如图:
此时想计算arr数组中有多少元素,将arr数组名传过去,并在f()中定义了数组arr[],按理说应该算出sz=10,但结果是1,为什么呢?
这是因为除了上面提到的arr两种特例,传入的arr实际是&arr[0](数组传参的实质是传入首元素的地址),形参本质也应使用指针变量来接收地址,此时()中的int arr[]等价于int arr,在X86环境下算出sz为1(指针大小为4个字节)。所以在外面的函数中不能求数组元素个数,只能在main函数中求*。
四·写一个函数,对一个整型数组的元素进行排序
冒泡排序(思路:相邻的两个元素进行比较,如果顺序不同就交换)
但这样有个弊端:就是如果原数组为9,0,1,2,3,4,5,6,7,8时,本来只用把9挪到后面就行了,但该程序需要继续运行,知道遍历检查完所有元素才结束,比较费时。
接下来对其优化:
定义一个变量flg=1(先假设有序为1),一旦执行交换顺序的语句,flg=0,表示无序;如果一趟下来flg=1,表示本来就有序,就不用执行下面的循环了,跳出。
如:原数组为9,0,1,2,3,4,5,6,7,8时,用改进的方法需要比较17次
原方法:45次