精华内容
下载资源
问答
  • c++ 对象作为参数,指针作为参数,引用作为参数

    千次阅读 多人点赞 2018-10-14 22:53:44
    c++ 对象作为参数,指针作为参数,引用作为参数

    c++ 参数传递方式有三种,分别为:传对象,传引用和传指针,那这三种传递方式之间到底有什么区别呢?

    传对象:是将实参对象的值传递给形参对象,是单项传递,在函数中修改形参的值时,不会影响到原来实参的值

    传引用:把实参对象名传给形参对象名,形参对象名就成为实参对象名的别名,实参和形参代表同一个对象,所以改变形参,就是改变实参对象的值.

    传指针:将指向对象的指针作为函数的参数,形参是对象的指针,实参是对象的地址值, 通过改变形参的值来改变实参的地址指向,形参传递的就是实参本身,所以当在函数中改变形参的值时,改变的就是原来实参的值.

    引用和指针有什么区别?
    引用和指针有形式之处,都会对内存地址上存在的变量进行修改,但它不占用新的地址,从未节省开销.

    展开全文
  • 如何正确使用指针(指针作为输出型参数)与结构体指针作为函数参数 外部定义一个结构体类型指针变量,使用##结构体指针里面的内嵌指针,返回值,双重指针##方式进行地址传递

    如何正确使用指针(指针作为输出型参数)与结构体指针作为函数参数

    指针作为输出型参数

    1. 指针作为输出型参数,通俗的理解,指针作为某一函数的实参,在函数内部发生改变后,外部的值也能跟着发生变化
    2. 类比外部的int a作为函数形参并能够传出来,要用指针形式,外部的指针作为函数形参并能够传出来,要使用指针的指针作为形参类型,其实它们的本质原理是一样的,都是传了变量的内存地址给函数
    程序1:
    void myMalloc(char *s) //在函数中分配内存,再返回 
    { 
    	s=(char *) malloc(100); 
    } 
    void main() 
    { 
    	char *p=NULL; 
    	myMalloc(p); //这里的p实际还是NULL,p的值没有改变
    	if(p) free(p); 
    } 
    程序2void myMalloc(char **s) //指针的指针,双重指针类型
    { 
       *s=(char *) malloc(100); 
     } 
    void main()     
    { 
    	char *p=NULL; 
    	myMalloc(&p); //这里的p可以得到正确的值
    	if(p) 
    		free(p); 
    } 
    

    指针作为输出型参数本质

    1. 指针变量就是一普通变量,当定义了一个变量,操作系统会为其分配相应的内存单元,内存里面存放的都是多个0和1组成的二进制数。
    2. 函数参数传递都是值传递
    3. 左值和右值,变量做左值,指向的是变量的内存空间,变量做右值,含义为将变量内存中存放的值取出来
    4. 取地址符&,与解地址符 *

    假设有一变量 char *a = null;
    假设有一函数 func(char *x) {x = ‘a’;}
    调用func(a)之后,a还是为null。

    调用中间的处理过程:func 临时定义了一个变量 char *x,函数内部使用的是x,而不是直接使用a,然后做了x=a的动作。函数内部一直都是在对x进行操作,故不会改变到a的值。

    将函数换成func(char **x) {*x=‘a’;}
    调用func(&a)之后,a的值为字符’a’。

    调用中间的处理过程:func 临时定义了一个变量 char **xx,函数内部使用的是x,然后做了x=&a的动作,则x变量存放了a的内存地址,函数内部对x进行解地址,即将x变量对应的内存中的那一串0101组成的二进制拿出来,这一串0101组成的二进制就是a的内存地址,*x=‘a’ 即向该空间写值。

    结构体指针就是一普通指针变量

    结构体指针作为函数参数

    void fb_open(struct framebuffer *fb)//指针
    {
        ...
    }
    
    void main()
    {
        struct framebuffer fb0;
        fb_open(&fb0);//取地址符&
        
    	struct framebuffer* fb1;//需要给这个指针分配实体
    	fb1 = (struct framebuffer*)malloc();
        fb_open(fb1);//这时就不用取地址符,fb1中的成员的值在fb_open中被改变会影响
    }
    

    详细例子说明

    #include <stdio.h>
    #include <stdlib.h>
    
    struct test_t{
        int *p;
        
        int a;
        int b;
        int c;
        int d;
    };
    
    //函数外部使用malloc测试函数 (函数形参为结构体类型)
    void func1(struct test_t * test)
    {
        test->a += 1;
        printf("test->a = %d.\n", test->a); 
    }
    
    /* 以下为函数内部使用malloc测试函数 (函数形参为结构体类型) */
    void func2(struct test_t * test)
    {   
        test = (struct test_t *)malloc(sizeof(struct test_t));
        test->b = 1;
        printf("test->b = %d.\n", test->b);
    }
    
    //...func3...
    
    
    void func4(struct test_t **test)
    {
        *test = (struct test_t *)malloc(sizeof(struct test_t));
        (*test)->d = 1;
        printf("test->d = %d.\n", (*test)->d);
    }
    
    
    void func_p(struct test_t * test)
    {
        test->p = (int *)malloc(sizeof(struct test_t));
    }
    
    int main(void)
    {
        //使用案例1:函数外malloc
        struct test_t * t1;
        t1 = (struct test_t *)malloc(sizeof(struct test_t));
        t1->a = 1;
        func1(t1);//这样使用,t1->a的值就会改变,和func4(struct test_t **test)区分
        printf("test->a = %d.\n", t1->a);
        free(t1);
        
        
        //有时候需要在函数里面malloc,如下:
    #if 0
        //使用案例2:错误使用,编译通过,运行触发段错误
        struct test_t *t2 = null;
        func2(t2);
        printf("test->b = %d.\n", t2->b);
        free(t2);
    #endif
    
    #if 1    
        //但是可以在结构体里声明一个指针成员,然后如下使用
        //(实际上原理和案例1是一样的,外部需要有实体,但是这里还提出来,是因为想说一下free的问题)
        //为结构体内部的指针分配内存还是经常遇到的,包含该指针的结构体也是malloc而来的,但是有时只记得free最外层的指针
        struct test_t * t0;
        t0 = (struct test_t *)malloc(sizeof(struct test_t));
        func_p(t0);
        printf("test->p = %p.\n", t0->p);
        free(t0->p);//不会触发段错误,注意free这个指针,还要注意先free这个指针,再free t0
        free(t0);
    #endif
        
        
    #if 0
        //使用案例3:
        struct test_t * t3;
        
        t3 = 返回值为struct test_t *的func3函数;
        ...
    #endif     
        
        //使用案例4:(func4形参使用双重指针类型)
        struct test_t * t4;
        func4(&t4);
        printf("test->d = %d.\n", t1->d);
        free(t4);
        
        //个人常用的就上面几种,当然还有这里没列出来的使用方式
        
        /** 总结
         * >> 函数使用指针类型形参以提高效率     
         * (1)外部定义指针变量再malloc分配
         * (2)函数外部的指针在函数内部malloc后能得到分配的内存地址的两种方式:双重指针和返回值
         * 多多编程多多体会
         */
        return 0;
    }
    
    
    打印内容:
    test->a = 2.
    test->a = 2.
    test->p = 0x81ed020.
    test->d = 1.
    test->d = 1.
    

    :在C语言中,使用结构体的时候 “->” 和 “." 的区别?

    定义的结构体如果是指针,访问成员时就用->
    如果定义的是结构体变量,访问成员时就用.
    例如:
    struct AAA {
        int a;
        char b;
    };
    struct AAA q; 访问成员就用:q.a;
    struct AAA *p; 访问成员就用:p->a;
    
    展开全文
  • c语言指针作为函数的参数

    万次阅读 多人点赞 2018-07-09 22:00:43
    指针变量作为参数也不例外,但是可以改变实参指针变量所指向的变量的值。 #include &lt;stdio.h&gt; void swap1(int x,int y),swap2(int *px,int *py),swap3(int *px,int *py); int main(vo...
     

    在c语言中实参和形参之间的数据传输是单向的“值传递”方式,也就是实参可以影响形参,而形参不能影响实参。指针变量作为参数也不例外,但是可以改变实参指针变量所指向的变量的值。

    #include <stdio.h>
    void swap1(int x,int y),swap2(int *px,int *py),swap3(int *px,int *py);
    int main(void)
    {
    	int a=1,b=2;
    	int *pa=&a,*pb=&b;
    	swap1(a,b);
    	printf("s1:a=%d,b=%d\n",a,b);
    
    	a=1,b=2;
    	swap2(pa,pb);
    	printf("s2:a=%d,b=%d\n",a,b);
    
    	a=1,b=2;
    	swap3(pa,pb);
    	printf("s3:a=%d,b=%d\n",a,b);
    	
    	return 0;
    }
    void swap1(int x,int y){
    	int t;
    	t=x;
    	x=y;
    	y=t;
    }
    
    void swap2(int *px,int *py){
    	int t;
    	t=*px;
    	*px=*py;
    	*py=t;
    }
    
    void swap3(int *px,int *py){
    	int *pt;
    	pt=px;
    	px=py;
    	py=pt;
    }

    结果:

    第一个swap1函数运行结果是:x=2   y=1.但是第一个函数的形参是(int x,int y),实参是(int a,int b)。因为实参可以影响形参,而形参不可以影响实参。所以a,b的值是不变的。如图:

                 

    第二个swap2函数由图可知,pa和px都是a的地址,pb和py都是b的地址。此函数改变*px,*py的值。因为*px和a在同一储存单元,*py和b在同一储存单元。以改变实参指针变量所指向的变量的值。所以如图*pa和*pb的值也改变了,最后输出结果也就改变了。

    第三个swap3同样的道理,如上图直接改变了形参指针px和py的值,改变的只是地址,地址所对应的值没有改变,又因为形参是不会影响实参,所以pa和pb没有改变。所以a,b值没有改变。

    展开全文
  • 文章摘自“微学苑”,微学苑主讲C、C++和Shell ... 指针在函数中的使用也是十分广泛的。某些情况下,将指针作为函数的参数或函数的返回值会给我们带来方便。而某些情况下,我们又...指针作为参数 我们在上一章我们已

    文章摘自“微学苑”,微学苑主讲C、C++和Shell

    Original URL: http://see.xidian.edu.cn/cpp/biancheng/view/50.html


    指针在函数中的使用也是十分广泛的。某些情况下,将指针作为函数的参数或函数的返回值会给我们带来方便。而某些情况下,我们又不得不将指针作为函数的参数或函数的返回值。

    指针作为参数

    我们在上一章我们已经了解向函数传递数组的实质是向函数传递数组首元素的地址。我们又知道数组名是一个指向数组首元素的指针常量。 所以我们认为,向函数传递数组是将指针作为参数的特殊形式。

    由于指针可以直接操作内存中的数据,所以它可以用来修改实参。 这个功能和引用是类似的。

    下面我们来看一段程序,了解指针作为参数时的上述两个特点:(程序8.6.1)
    #include "iostream.h"
    void arrayCopy(int *src,int *dest,int size);//复制数组元素
    void display(const int *array,int size);//输出数组元素
    int main()
    {
       int a[]={3,4,5,6,3,1,6};
       int b[7];
       arrayCopy(a,b,sizeof(a)/sizeof(int));//把数组a的元素依次复制到数组b中
       cout <<"The data of array a is:";
       display(a,sizeof(a)/sizeof(int));
       cout <<"The data of array b is:";
       display(b,sizeof(b)/sizeof(int));
       return 0;
    }
    void arrayCopy(int *src,int *dest,int size)
    {
       for (int i=0;i<size;i++)
       {
          dest[i]=src[i];//修改了实参数组元素
       }
       cout <<size <<" data Copied." <<endl;
    }
    void display(const int *array,int size)//const用来保护指针指向的数据
    {
       for (int i=0;i<size;i++)
       {
          cout <<array[i] <<" ";
       }
       cout <<endl;
    }

    运行结果:
    7 data Copied.
    The data of array a is:3 4 5 6 3 1 6
    The data of array b is:3 4 5 6 3 1 6

    根据arrayCopy函数,不难看出传递数组和传递指针是完全相同的。而通过指针的间接引用或数组操作,我们可以在函数内实现对实参的修改。这就是arrayCopy函数能够实现复制功能的原因。

    不过,将指针作为函数参数的副作用仍然不容我们忽视。 指针和引用虽然都能够修改实参,但是指针却更加危险。 因为引用仅限于修改某一个确定的实参,而指针却可以指向内存中的任何一个数据,通过间接引用就能够在一个函数内修改函数外甚至系统中的数据了 。这样一来,函数的黑盒特性就被破坏了,系统也因此变得不再安全。对于程序员来说,将指针作为函数参数可能把函数内的问题引到函数外面去,使得调试程序变得非常困难。所以,我们要认识到使用指针的两面性,谨慎对待指针做函数参数。

    为了避免指针作为函数参数导致数据被意外修改,我们可以使用const来保护指针指向的数据,如程序8.6.1中的display函数。

    指针作为返回值

    和别的数据类型一样,指针也能够作为函数的一种返回值类型。我们把返回指针的函数称为指针函数。在某些情况下,函数返回指针可以给我们设计程序带来方便。而且此时通过间接引用,函数的返回值还可以作为左值。

    下面我们来看一段程序,了解函数如何返回指针:(程序8.6.2)
    #include "iostream.h"
    int * max(int *array,int size);//返回值类型是int *,即整型指针
    int main()
    {
       int array[]={5,3,6,7,2,1,9,10};
       cout <<"The Max Number is " <<*max(array,sizeof(array)/sizeof(int)) <<endl;//间接引用返回的指针
       return 0;
    }
    int * max(int *array,int size)//寻找最大值
    {
       int *max=array;
       for (int i=0;i<size;i++)
       {
          if (array[i]>*max)
          max=&array[i];//记录最大值的地址
       }
       return max;
    }

    运行结果:
    The Max Number is 10

    需要注意的是,返回的指针所指向的数据不能够是函数内声明的变量。 道理很简单,我们在第六章已经说明,一个函数一旦运行结束,在函数内声明的变量就会消失。就好像下课同学们都走了,教室里的某一个座位到底有没有坐着谁我们无法确定。所以指针函数必须返回一个函数结束运行后仍然有效的地址值。
    展开全文
  • 数组传参,指针作为参数

    千次阅读 2018-06-09 17:01:28
    1.一维数组作为参数(形参) 2.二维数组 二、指针传参 1.一级指针传参(形参) 三、指针数组,数组指针传参 1.指针数组传参 2.数组指针传参 总结: 一、数组传参 1.一维数组作为参数(形参) 一维数组作为...
  • 方法:需要将指向该指针的指针作为参数传递给函数,再在函数中修改(即指针的指针作为参数传递给函数) //函数定义 void user(void ** ppanonymity){ MyClass* target=new MyClass(); *ppanonymity=target; } ...
  • C语言指针作为参数的传递问题

    千次阅读 2021-06-30 14:28:36
    (注意:C语言中没有引用传递,C++才引用传递,因为很多C语言环境是C++编译器编译,使得C看起来支持引用传递,导致很多网上很多blog都把引用传递归C语言参数传递的一类, 当使用Microsoft Visual C++ 2010 ...
  • 指针作为参数传递

    千次阅读 2010-05-28 00:33:00
    这几天在学习C过程中,在使用指针作为函数参数传递的时候出现了问题,根本不知道从何得解:源代码如下: createNode(BinNode *tree,char *p) { tree = (BinNode *) malloc(sizeof(BinNode)); tree->data = *p; }...
  • 指针和双指针作为函数参数

    千次阅读 2016-02-25 20:25:19
    1. 每个变量都一个地址和初值,初值可以被改变,这个值的类型可以是int,char,double,float等。...1. 变量作为函数参数: void var(int a){ a = 3; } int main(void){ int b = 2;
  • C语言指针之数组指针作为参数

    千次阅读 2019-07-06 16:52:35
    //数组名作为函数参数 //如果一个实参的数组 想在函数中改变数组的值 //实参和形参对应的是可以四种 //1)实参和形参都是数组名 // int a[5]; //能引用的下标a[0] - a[4] // a[0] = 85; // a[1] = 70; // ...
  • 结构体、结构指针作为函数参数

    千次阅读 2019-05-20 07:19:25
    结构体、结构指针作为函数参数 结构体、结构体指针作为函数的参数现在应用的非常广泛,但一些细微之处还需要引起注意。本文将讨论其作为形参和实参的区别。 结构体作为参数 将结构体作为函数的参数,目的是通过...
  • 结构体和结构体指针作为参数传递

    千次阅读 2018-08-14 13:53:01
    结构体和结构体指针作为参数传递其实也是比较好理解的,因为之前我们应该学习过地址传参数的问题,其实是一样的,主要优点是地址比传递整个结构体快,具体可参考链接 结构体作为参数传递: #include&lt;...
  • 函数指针作为函数参数

    千次阅读 2015-10-14 09:32:43
    定义指针用一个比较粗浅的方法来说就是把原来的变量名换掉并且前面加星号,比如这里就是把a换成p并且前面加星号,就定义了一个可以指向a的指针 同理,如果要定义一个指向函数的指针,那么也只要把函数名做类似的...
  • C语言数组作为参数会退化为指针,这是什么意思?指针和数组的不同是什么
  • 一、auto_ptr和shared_ptr作为普通参数指针参数  我想这是我们使用最多的,直接传过去好了,基本上没什么好担心的。例如:  1.  T* pt = new T;   auto_ptr ap( pt);  // void f1(auto_ptr ap);  f1...
  • 指针的引用作为函数参数有

    千次阅读 2014-02-17 20:05:00
    一句话总结 用指针的引用作为某函数的参数来传递,其目的就是为了在这个函数里面改变该指针的值(就是改变指针所指向的对象)。
  • 我能否void** 指针作为参数, 使函数按引用接受一般指针? 不可移植。C 中没有一般的指针的指针类型。void* 可以用作一般指针只是因为当它和其它类型相互赋值的时候, 如果需要, 它可以自动转换成其它类型; 但是, ...
  • 指针地址作为参数传递

    千次阅读 2017-05-11 19:14:00
    在做GPU高性能计算时遇到一个问题,在__host__中分配的GPU变量怎么在__host__间传递。其实这转换过来是一个函数...取该指针的地址,作为一个新的指针传递。 如 A()中 double * T,需要传参到B()中,并且可修改T的地址
  • 函数指针作为参数的语法如下所示: int compare(int a, int b){ return (a > b) ? a : b; } void function(int x, int y, int (*compare)(int, int)){ //... (*compare)(3, 4); //... } int m
  • C++指向函数的指针作为函数参数

    千次阅读 2018-12-05 19:42:12
    示例: # include ...//也可以写(*function)(x, y) } int main ( ) { int answer = operation ( 1 , 2 , add ) ; //addition前可以添加取地址符& cout answer ; }
  • 0·说明 文章里的观点来自网络的总结,程序经过自己的验证,在VC6.0中可正常执行。 1.测试程序 /* ##结构体指针与结构体变量... 即一个结构体A,当它的指针作为参数传入函数func,那么在func中可以通过指针 改...
  • c++ 用指针将函数作为参数传参

    千次阅读 2018-05-16 14:38:05
    1.问题提出:当一个类的对象作为参数传递时,使用值传递和引用传递有什么区别? 比如: DateType ExampleFun(CString &amp;strFileName,...)与 DateType ExampleFun(CString strFileName,...)解答之前,我们...
  • 指针作为参数传入函数的陷阱

    千次阅读 2017-05-14 12:25:16
    的意思是把函数的第一个参数的值压入栈中存储。 这说明了什么? 说明了函数中的 *p 其实是一个临时变量,和主函数并不是同一个 *p 了。给临时变量申请内存并赋值当前不能反映到主函数的 *p 上,所以主函数的 *p 还是...
  • 结构体 结构体指针
  • 二级指针作为函数参数申请内存

    千次阅读 2015-11-04 22:19:56
    0:声明:这篇文章转自林锐的《高质量的C/C++编程指南》,如果想看电子版文档,请去下载【去下载】1:如果函数的参数是一个指针,不要指望指针去申请动态内存。示例7-4-1 中,Test 函数的语句 GetMemory(str, ...
  • 指针指针的引用作为参数——c++

    千次阅读 2015-09-19 21:57:50
    指针指针的引用作为参数–c++指针都清楚,存放变量地址的变量。... 作为参数传递时,这样指针的数值是可以改变的 ,表示: *&P fun(int * pA); // pA的数值在函数返回后不会变化 fun(int*& pA); // pA的数值

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 515,567
精华内容 206,226
关键字:

为什么指针作为参数有什么用