c语⾔中变量的引⽤传递和指针
掌握引⽤和指针的区别
引⽤型变量存储的是变量的地址,指针存储的也是变量的地址,所以本质上来说⼆者是⼀样的。
使⽤引⽤型变量,⼦函数中所有的操作会直接修改主函数中的实参。
正常情况下,使⽤变量的引⽤总是没有问题的,引⽤是地址的拷贝。
编程的本质不就是改变量么?通过引⽤型变量和指针型变量可以让⼦函数直接改主函数中的变量,⽽不再需要为形参开辟内存。
//⼦函数可以主函数前⾯声明,也可以在主函数中声明,总之⼀定要在调⽤前
//下⾯这个例⼦说明“不能企图通过改变形参的值来改变实参”
#include "stdafx.h"
#include <stdio.h>
void swap(int x,int y);
void main()
{
//void swap(int &x,int &y);
int a=3,b=5;
swap(a,b);
printf("a=%d b=%d\n",a,b);
}
void swap(int x,int y)
{
int temp;
temp=x;
x=y;
y=temp;
}
//运⾏结果:a b并未发⽣交换
如果不⽤指针做形参或者引⽤型变量做形参(如上所⽰), 程序在调⽤⼦函数时会为x y重新开辟内存,并将实参的值复制到x y中去,然后在swap函数中,x y确实发⽣交换了,但这跟主函数中的a b毫⽆关系呀,a b并未发⽣改变呀。⼦函数调⽤结束后形参所占内存⾃动释放。
引⽤型变量和指针其实是将主函数中变量的地址传递给了⼦函数,这样⼦函数直接去操作主函数中的变量,并不会再为形参开辟内存。
//通过引⽤型变量,⼦函数直接改主函数中定义的变量
#include "stdafx.h"
#include <stdio.h>
void swap(int &x,int &y);
void main()
{
//void swap(int &x,int &y);
int a=3,b=5;
swap(a,b);
printf("a=%d b=%d\n",a,b);
}
void swap(int &x,int &y)
{
int temp;
temp=x;
x=y;
y=temp;
}
c语言和c++区别//运⾏结果:完成交换
//通过引⽤型变量或者指针调⽤⼦函数,⼦函数会直接改主函数中的变量。
//⼦函数直接在实参地址上改变量,所以改之前如果需要备份就要备份。
//如果调⽤的⼦函数有返回值,就可以不⽤引⽤变量,函数调⽤时会为形参中的x,y开辟内存,将计算的结果返回给主函数后,形参开辟的内存会被释放掉。#include <stdio.h>
int add(int x,int y);
void main()
{
int a=3,b=5;
int sum=add(a,b);
printf("sum=%d\n",sum);
}
int add(int x,int y)
{
return x+y;
}
//使⽤引⽤型变量,⼦函数调⽤会直接对主函数中的变量做加法,不会为形参x y开辟内存,执⾏效率变⾼。
#include <stdio.h>
int add(int &x,int &y);
void main()
{
int a=3,b=5;
int sum=add(a,b);
printf("sum=%d\n",sum);
}
int add(int &x,int &y)
{
return x+y;
}
//关于引⽤型变量我再写个例⼦:
#include <stdio.h>
int add(int &x,int &y);
void main()
{
int a=3,b=5;
int sum=add(a,b);
printf("sum=%d\n",sum);
}
int add(int &x,int &y)
{
x=x+1;
y=y+1;
return x+y;
}
/*
运⾏结果:sum=10
程序执⾏流程:⽤了引⽤变量后,⼦函数不会再为形参开辟内存,⽽是直接对a b操作,在原来a的内存中对a加1变为4,在原来b的内存中对b加1变为6,
然后直接相加将10赋给sum,⼀句话来总结: ⽤了引⽤变量后,就不再为形参开辟内存,所有操作都是直接修改实参变量。
调⽤⼦函数会将主函数中的变量直接改掉,如果在主函数后⾯继续使⽤a b时,⼀定要注意这两个变量已经被修改了。
*/
/
/下⾯写⼀个调⽤排序的程序,当⽤数组名做实参时,相当于使⽤引⽤型变量,因为数组名就表⽰数组⾸元素的地址,这和引⽤型变量与指针是⼀样的
#include <stdio.h>
void sort(int arr[]);//声明
void main()
{
int a[]={9,8,7,6,5,4,3,2,1,0};//10个数.写成int[] a编译会报错(java中写法)
sort(a);//数组名代表数组⾸元素的地址
for(int i=0;i<10;i++)
printf("%d ",a[i]);
}
void sort(int arr[])
{
int min=0;
for(int i=0;i<9;i++)//10个数做9趟⽐较
{
min=i;//将min定义在循环外⾯,不然会在循环中重复定义(效率低)
for(int j=i+1;j<10;j++)//for中的起始条件和结束条件其实定义在循环外⾯,只有j++是循环体中的内容(深刻理解for和while的关系,能掌握⼆者的转换)
{
if(arr[j]<arr[min])
min=j;
}
int temp=arr[min];
arr[min]=arr[i];
arr[i]=temp;
}
}
/*
下⾯⽤指针做参数测试⼀下,形参和实参都是指针型变量。
事实上这⾥⾯指针型变量和数组名能随便替换,还可以选择数组名做实参,指针做形参。
数组名代表数组⾸元素的地址,并且这个地址可以赋给指针变量p
*/
#include <stdio.h>
void sort(int *arr);//声明
void main()
{
int a[]={9,8,7,6,5,4,3,2,1,0};//10个数
int* p=a;//将数组⾸元素的地址赋给指针变量p,*挨着int写还是p写都是可以的
sort(p);
for(int i=0;i<10;i++)
printf("%d ",a[i]);
}
void sort(int *arr)
{
int min=0;
for(int i=0;i<9;i++)//10个数做9趟⽐较
{
min=i;
for(int j=i+1;j<10;j++)
{
if(*(arr+j)<*(arr+min))//if(arr[j]<arr[min])
min=j;
}
int temp=arr[min];
arr[min]=arr[i];
arr[i]=temp;
}
}
//下⾯这个例⼦⽤数组名做实参,指针做形参。事实上(int *arr)和(int arr[])是⼀样的
#include <stdio.h>
void sort(int *arr);//声明
void main()
{
int a[]={9,8,7,6,5,4,3,2,1,0};//10个数
sort(a);//数组名做实参
for(int i=0;i<10;i++)
printf("%d ",a[i]);
}
void sort(int *arr)
{
int min=0;
for(int i=0;i<9;i++)//10个数做9趟⽐较
{
min=i;
for(int j=i+1;j<10;j++)
{
if(*(arr+j)<*(arr+min))//if(arr[j]<arr[min])
min=j;
}
int temp=arr[min];
arr[min]=arr[i];
arr[i]=temp;
}
}
我认为编程的两个难题,⼀个是多返回值,另⼀个是通过参数调⽤函数。(第⼆个问题总是不可避免的,需要参数调⽤的地⽅⼀定是需要的)解决多返回值的问题,可以使⽤引⽤传递,也可以使⽤下⾯这种⽅式。
// 将我们想要通过⼦函数调⽤改变的变量⾸先在主函数中定义好并赋初值,然后将这些变量的引⽤作为⼦函数的形参。
// ⼦函数调⽤结束后,主函数中的这些变量⾃然就被改了。
#include "stdafx.h"
#include <stdio.h>
void add(int &x,int &y,int &sum);//引⽤型变量会使⼦函数直接改主函数中的变量
void main()
{
int a=3,b=5;
int sum=0;
add(a,b,sum);//执⾏过这句代码后,sum值⾃然被改掉
printf("sum=%d\n",sum);
}
void add(int &x,int &y,int &sum)//将返回值直接定义为⼦函数的参数,这样返回值就能写为空了
{
sum=x+y;
}
//不⽤定义全局变量,通过返回值空的⼦函数到数组中的最⼤元素以及下标
#include "stdafx.h"
#include <stdio.h>
void searchMax(int arr[],int &max,int &index_max);//引⽤型变量会使⼦函数直接改主函数中的变量
void main()
{
int arr[]={2,23,89,1,90,112,34,13,234,89};
for(int i=0;i<10;i++){
printf("%d\t",arr[i]);
}
int max=-1;
int index_max=0;
searchMax(arr,max,index_max);
printf("max=%d\n",max);
printf("index_max=%d\n",index_max);
}
void searchMax(int arr[],int &max,int &index_max)//将返回值直接定义为⼦函数的参数,这样就不需要返回值{
for(int i=0;i<10;i++){
if(arr[i]>max){
max=arr[i];
index_max=i;
}
}
}
//这是使⽤全局变量的写法
#include "stdafx.h"
#include <stdio.h>
int searchMax(int arr[]);
int index_max=0;
void main()
{
int arr[]={2,23,89,1,90,112,34,13,234,89};
for(int i=0;i<10;i++){
printf("%d\t",arr[i]);
}
int max=searchMax(arr);
printf("max=%d\n",max);
printf("index_max=%d\n",index_max);
}
int searchMax(int arr[])
{
int max=-1;
for(int i=0;i<10;i++){
if(arr[i]>max){
max=arr[i];
index_max=i;
}
}
return max;
}
//将数组所有元素⾃增1,程序执⾏成功
//形参中使⽤(int arr[]),相当于引⽤型变量
/
/所有⽤数组做⼦函数参数的地⽅,都是引⽤传递。
#include "stdafx.h"
#include <stdio.h>
void changeArr(int arr[]);
void main()
{
int arr[]={2,23,89,1,90,112,34,13,234,89};
int i;
for(i=0;i<10;i++){ //不能将int i=0写在for()⾥⾯,这是c语法
printf("%d\t",arr[i]);
}
changeArr(arr);
for(i=0;i<10;i++){
printf("%d\t",arr[i]);
}
}
void changeArr(int arr[])
{
for(int i=0;i<10;i++){
arr[i]++;
}
}
/
/数组不是c语⾔中的基本数据类型,所以不能返回数组,只能返回⼀个指向数组的指针
// 因为数组的内存开辟在堆上,所以⼦函数结束后并不会被释放,⼦函数只需要将指针返回给主函数,主函数可随时访问。
#include "stdafx.h"
#include<iostream>
using namespace std;
int* Array()
{
int *a;
a=new int [10];
for(int i=0;i<10;i++)
{
a[i]=i+1;
}
return a;
}
void main()
{
int *b;
b=Array();
for(int i=0;i<10;i++)
cout<<b[i]<<" ";
cout<<endl;
}
//所有⽤数组做⼦函数参数的地⽅,都是引⽤传递。即如果⽤数组做⼦函数参数,主函数中的参数⼀定会被改掉,所以如果需要备份就要提前拷贝好。
#include "stdafx.h"
#include <stdio.h>
void changeArr(int arr[]);
void main()
{
int arr[]={2,23,89,1,90,112,34,13,234,89};
int arr_copy[]={2,23,89,1,90,112,34,13,234,89};
int i;
changeArr(arr_copy);
printf("修改之前的arr:\n");
for(i=0;i<10;i++){
printf("%d\t",arr[i]);
}
printf("修改之后的arr:\n");
for(i=0;i<10;i++){
printf("%d\t",arr_copy[i]);
}
}
void changeArr(int arr[])
{
for(int i=0;i<10;i++){
arr[i]++;
}
}
//之前做图像处理课作业的时候,想对⼀张图灰度化,但是原图⼜要保留下来,就在主函数中申请⼀个和原图等⼤的矩阵,全填上0,
然后将原图的指针和空⽩图的指针(或者数组名)全部作为参数传递给灰度化函数,灰度化函数根据原图像素修改后重写空⽩图像,执⾏结束后主函数中的空⽩图⾃然被写成灰度图了,
这样也不需要返回值。
//这种⽅式⽐在⼦函数中创建数组,开辟内存,然后返回指针的⽅式好。当然这种⽅式也是可以的,因为new开辟的内存在堆上,⼦函数结束后并不会被释放,所以⼦函数把指针返回给主函数,主函数可随时访问。
#include "stdafx.h"
#include <stdio.h>
void changeArr(int arr[],int arr_copy[]);
void main()
{
int arr[]={2,23,89,1,90,112,34,13,234,89};
int arr_copy[]={0,0,0,0,0,0,0,0,0,0};
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论