九、结构体—函数之间数据传递

合集下载

C语言中函数参数传递

C语言中函数参数传递

C语⾔中函数参数传递C语⾔中函数参数传递的三种⽅式(1)值传递,就是把你的变量的值传递给函数的形式参数,实际就是⽤变量的值来新⽣成⼀个形式参数,因⽽在函数⾥对形参的改变不会影响到函数外的变量的值。

(2)地址传递,就是把变量的地址赋给函数⾥形式参数的指针,使指针指向真实的变量的地址,因为对指针所指地址的内容的改变能反映到函数外,能改变函数外的变量的值。

(3)引⽤传递,实际是通过指针来实现的,能达到使⽤的效果如传址,可是使⽤⽅式如传值。

说⼏点建议:如果传值的话,会⽣成新的对象,花费时间和空间,⽽在退出函数的时候,⼜会销毁该对象,花费时间和空间。

因⽽如果int,char等固有类型,⽽是你⾃⼰定义的类或结构等,都建议传指针或引⽤,因为他们不会创建新的对象。

例1:下⾯这段代码的输出结果为:#include<stdio.h>void change(int*a, int&b, int c){c=*a;b=30;*a=20;}int main ( ){int a=10, b=20, c=30;change(&a,b,c);printf(“%d,%d,%d,”,a,b,c);return 0;}结果:20 30 30解析:1,指针传参 -> 将变量的地址直接传⼊函数,函数中可以对其值进⾏修改。

2,引⽤传参 -> 将变量的引⽤传⼊函数,效果和指针相同,同样函数中可以对其值进⾏修改。

3,值传参 -> 在传参过程中,⾸先将c的值复制给函数c变量,然后在函数中修改的即是函数的c变量,然后函数返回时,系统⾃动释放变量c。

⽽对main函数的c没有影响。

例2:#include<stdio.h>void myswap(int x, int y){int t;t=x;x=y;y=t;}int main(){int a, b;printf("请输⼊待交换的两个整数:");scanf("%d %d", &a, &b);myswap(a,b); //作为对⽐,直接交换两个整数,显然不⾏printf("调⽤交换函数后的结果是:%d 和 %d\n", a, b);return 0;}#include<stdio.h>void myswap(int *p1, int *p2){int t;t=*p1;*p1=*p2;*p2=t;}int main(){int a, b;printf("请输⼊待交换的两个整数:");scanf("%d %d", &a, &b);myswap(&a,&b); //交换两个整数的地址printf("调⽤交换函数后的结果是:%d 和 %d\n", a, b);return 0;}#include<stdio.h>void myswap(int &x, int &y){int t;t=x;x=y;y=t;}int main(){int a, b;printf("请输⼊待交换的两个整数:");scanf("%d %d", &a, &b);myswap(a,b); //直接以变量a和b作为实参交换printf("调⽤交换函数后的结果是:%d 和 %d\n", a, b);return 0;}第⼀个的运⾏结果:输⼊2 3,输出2 3第⼆个的运⾏结果:输⼊2 3,输出3 2第三个的运⾏结果:输⼊2 3,输出3 2解析:在第⼀个程序中,传值不成功的原因是指在形参上改变了数值,没有在实参上改变数值。

函数参数传递的两种方式

函数参数传递的两种方式

函数参数传递的两种方式在编写函数时,函数的参数传递方式是非常关键的。

函数的参数传递方式分为值传递和引用传递两种方式。

本文将会对这两种方式进行详细介绍和比较。

一、值传递值传递是指函数参数在传递的过程中,实参的值被复制到函数的形参中进行传递。

这意味着,当函数在处理参数时,它只能获取到形参的副本,而无法改变原来实参的值。

因此,变量的值无法在函数内部改变。

当函数执行完毕后,这些参数的值将会被销毁。

在C语言中,基本数据类型、结构体以及数组等都属于值类型,它们默认的传递方式是值传递。

下面的例子演示了值传递的过程:```cvoid swap(int a, int b){int temp = a;a = b;b = temp;}上面的代码中,函数swap()将x和y的值交换,但由于传递的是参数的副本,函数并不能够改变x和y的值。

因此,最终输出结果还是原来的值。

优点:1. 值传递的方法比较简单。

2. 对于实参的值不需要保护的情况下,使用值传递往往会更高效。

3. 传递副本避免了不必要的占内存,对于内存的规划来说,非常有利。

1. 对于一些要修改实参值的情况,值传递无法完成。

2. 对于大数据的复制,值传递可能会导致内存的占用率上升。

二、引用传递引用传递是指将实参的地址传给函数,以便在函数内部操作实参的值。

因为直接传入的是实参的地址,所以函数内部对参数的操作直接就是作用于实参本身,可以改变参数的值。

引用传递使用&符号来传递地址。

在C语言中,使用指针类型传递参数可以实现引用传递。

下面的例子演示了引用传递的过程:上面的代码中,函数swap()使用指针类型参数,对于参数进行了引用传递,可以更改实参的值。

因此,在函数执行完成后,x和y的值已经被交换。

2. 可以省去大量复制数据的开销,加快函数的调用速度。

3. 引用传递可以使得函数在执行过程中,能够访问外部变量的地址,比较灵活。

2. 引用传递也会占用一些额外的空间。

综合比较在选择传递方式时,应该根据函数的实际需求进行选择。

C语言关于结构体做参数传递

C语言关于结构体做参数传递

C语言关于结构体做参数传递C语言中结构体类型可以作为函数的参数进行传递。

通过结构体做参数传递,可以将一个或多个相关的数据封装到一个结构体中,然后直接传递结构体作为参数,从而简化函数调用过程,提高程序可读性和维护性。

在C语言中,结构体是一种用户自定义的数据类型,它由多个不同类型的成员组成。

结构体的声明通常放在函数外部,以便于多个函数共享同一种数据结构。

下面我们来探讨几种关于结构体做参数传递的常见使用方式以及它们的特点。

首先是结构体值传递。

结构体作为函数参数传递时,会将结构体的每个成员的值拷贝一份传递给函数参数,函数内部对参数进行的修改不会影响外部的原结构体。

下面是一个示例:```c#include <stdio.h>struct Personchar name[20];int age;};void displayPerson(struct Person p)printf("Name: %s\n", );printf("Age: %d\n", p.age);int maistruct Person p1 = {"Tom", 20};displayPerson(p1);return 0;```在这个示例中,displayPerson函数接受一个Person类型的参数p,并打印其成员name和age。

当displayPerson函数调用时,会将p1的值拷贝到参数p,所以在函数内部修改p的值不会影响p1的值。

输出结果为:```Name: TomAge: 20```其次是结构体指针传递。

结构体指针可以在函数内部直接修改结构体的值,从而实现对原结构体的修改。

下面是一个示例:```c#include <stdio.h>struct Pointint x;int y;};void movePoint(struct Point *p, int dx, int dy)p->x += dx;p->y += dy;int maistruct Point p = {1, 2};movePoint(&p, 3, 4);printf("New coordinates: (%d, %d)\n", p.x, p.y);return 0;```在这个示例中,movePoint函数接受一个Point类型的指针p,并将x和y成员分别增加dx和dy的值。

c语言函数参数传递方式

c语言函数参数传递方式

c语言函数参数传递方式C语言是一种广泛使用的编程语言,函数参数传递方式是C语言中非常重要的概念之一。

函数参数传递方式可以分为按值传递、按址传递和按引用传递三种方式。

本文将针对这三种方式进行详细讲解。

一、按值传递按值传递是指在函数调用时,将实际参数的值复制给形式参数,函数内部对形参的修改不会影响到实际参数的值。

这种方式适用于参数较少、参数值不需要在函数内部被修改的情况。

在按值传递的方式下,函数在栈内存中为形参分配空间,并将实参的值复制到形参中。

函数执行结束后,栈内存中的形参被销毁,不会影响到实参的值。

二、按址传递按址传递是指在函数调用时,将实际参数的地址传递给形式参数,函数内部通过指针对实参进行操作,可以修改实参的值。

这种方式适用于需要在函数内部修改实参值的情况。

在按址传递的方式下,函数在栈内存中为形参分配空间,并将实参的地址传递给形参。

函数内部通过指针对实参进行操作,修改实参的值。

由于传递的是地址,所以函数内部对形参的修改会影响到实参。

三、按引用传递按引用传递是C++中的特性,其本质是通过指针来实现的。

在C语言中,可以通过传递指针的方式来模拟按引用传递。

按引用传递的特点是可以修改实参的值,并且不需要像按址传递那样使用指针操作。

在按引用传递的方式下,函数在栈内存中为形参分配空间,并将实参的地址传递给形参。

函数内部通过引用的方式操作形参,可以直接修改实参的值。

由于传递的是地址,所以函数内部对形参的修改会影响到实参。

需要注意的是,按引用传递需要使用指针来实现。

在函数调用时,需要将实参的地址传递给形参,即传递一个指向实参的指针。

函数内部通过解引用指针来操作实参,可以达到修改实参的目的。

总结:C语言中的函数参数传递方式包括按值传递、按址传递和按引用传递三种方式。

按值传递适用于参数较少、参数值不需要在函数内部被修改的情况;按址传递适用于需要在函数内部修改实参值的情况;按引用传递需要使用指针来实现,通过传递实参的地址来实现对实参的修改。

c语言结构体数组传参

c语言结构体数组传参

c语言结构体数组传参C语言结构体数组传参结构体数组是C语言中常用的数据类型,它能够存储一组相关的数据,并且可以方便地传递给函数进行处理。

本篇文章将从介绍结构体数组的定义开始,逐步详解结构体数组的传参方法和使用技巧。

一、结构体数组的定义结构体是一种用户自定义的数据类型,它能够将多个不同类型的变量组合成为一个整体。

结构体数组是由多个相同类型的结构体变量组成的数组。

在C语言中,可以通过如下方式定义一个结构体数组:cstruct student {int id;char name[20];int age;} stuArr[100];上述代码定义了一个结构体数组stuArr,其中每个元素都是一个包含id、name和age三个成员变量的结构体变量。

stuArr的长度为100,即可以存储100个学生的信息。

二、结构体数组的传参结构体数组作为函数的参数时,可以通过值传递或指针传递的方式进行。

1. 值传递方式值传递是将结构体数组的副本传递给函数,函数对副本的修改不会影响到原数组。

cvoid printStudents(struct student arr[], int n) {for (int i = 0; i < n; i++) {printf("ID: d\n", arr[i].id);printf("Name: s\n", arr[i].name);printf("Age: d\n", arr[i].age);}}int main() {struct student stuArr[3] = {{1001, "Tom", 18},{1002, "Jerry", 19},{1003, "Alice", 20}};printStudents(stuArr, 3);return 0;}上述代码中,printStudents函数接收一个结构体数组和数组的长度作为参数,遍历数组并打印每个学生的信息。

c语言结构体作为函数参数

c语言结构体作为函数参数

c语言结构体作为函数参数一、引言C语言中,结构体是一种非常重要的数据类型,可以将多个不同类型的变量封装在一个结构体中,方便管理和使用。

在函数中使用结构体作为参数,可以将多个相关变量作为一个整体传递给函数,提高程序的可读性和可维护性。

本文将详细介绍C语言中如何使用结构体作为函数参数,并且提供一个全面详细的函数示例。

二、结构体作为函数参数1. 声明结构体类型在使用结构体作为函数参数之前,需要先声明一个结构体类型。

例如,我们定义一个名为Person的结构体类型,包含姓名、年龄和性别三个成员变量:```typedef struct {char name[20];int age;char sex;} Person;```2. 定义函数并传递结构体参数接下来我们定义一个名为printPerson的函数,并将Person类型的变量作为参数传递给它:```void printPerson(Person p) {printf("Name: %s\n", );printf("Age: %d\n", p.age);printf("Sex: %c\n", p.sex);}```在这个函数中,我们首先输出了传入的Person类型变量p中的姓名、年龄和性别三个成员变量。

3. 调用函数并传递结构体参数现在我们可以调用printPerson函数,并传递一个Person类型的变量作为参数:```int main() {Person p = {"Tom", 20, 'M'};printPerson(p);return 0;}```在main函数中,我们定义了一个名为p的Person类型变量,并初始化了它的姓名、年龄和性别三个成员变量。

接下来,我们调用printPerson函数,并将p作为参数传递给它。

4. 输出结果最终程序会输出以下结果:```Name: TomAge: 20Sex: M```三、结构体指针作为函数参数除了使用结构体变量作为函数参数之外,还可以使用结构体指针作为函数参数。

计算机专业研究生复试-C语言程序设计面试简答题

计算机专业研究生复试-C语言程序设计面试简答题

C语言程序设计1.简述C语⾔采取了哪些措施提⾔执⾔效率●使⽤指针:有些程序⽤其他语⽤也可以实现,但C能够更有效地实现;有些程序⽤法⽤其它语⽤实现,如直接访问硬件,但C却可以。

正因为指针可以拥有类似于汇编的寻址⽤式,所以可以使程序更⽤效。

●使⽤宏函数:宏函数仅仅作为预先写好的代码嵌⽤到当前程序,不会产⽤函数调⽤,所以仅仅是占⽤了空间,⽤使程序可以⽤效运⽤。

在频繁调⽤同⽤个宏函数的时候,该现象尤其突出。

函数和宏函数的区别就在于,宏函数占⽤了⽤量的空间,⽤函数占⽤了时间。

●使⽤位操作:位操作可以减少除法和取模的运算。

在计算机程序中数据的位是可以操作的最⽤数据单位,理论上可以⽤"位运算"来完成所有的运算和操作。

灵活的位操作可以有效地提⽤程序运⽤的效率。

●将汇编指令嵌⽤到C 语⽤程序中,汇编语⽤是效率最⽤的计算机语⽤,因此在C语⽤程序中嵌⽤汇编,从⽤充分利⽤⽤级语⽤和汇编语⽤各⽤的特点。

●系统调用:在C语⽤程序中可以调⽤操作系统级的API,从⽤提⽤程序的运⽤效率。

●条件编译:C语⽤源程序中加上条件编译,让编译器只对满⽤条件的代码进⽤编译,将不满⽤条件的代码舍弃,可以减少编译及执行程序代码量。

●循环嵌套中将较长循环设为内置循环,较短循环设为外置循环,以减少cpu跨切循环层的次数,提⽤程序的运⽤效率。

(操作系统页⽤置换相关,减少页⽤置换次数)●其它诸如寄存器变量、联合体、编译器优化等手段提⽤执⽤效率。

2.if…else和switch区别总结:都是条件选中语句。

但switch语句只能取代if语句的一部分功能。

●比较的范围不同:if 语句可做各种关系比较(只要是boolean 表达式都可以用if 判断)switch语句只能做等式比较,即只能对基本类型进行数值比较。

(switch只能做几个数据类型的等式比较,实现非等式效率低,)switch之后括号内的表达式只能是整型(byte、short、char和int)、枚举型或字符型表达式,不能是长整型或其他任何类型。

c语言函数调用时参数传递方式的有哪几种,分别简述他们的传递方式

c语言函数调用时参数传递方式的有哪几种,分别简述他们的传递方式

c语言函数调用时参数传递方式的有哪几种,分别简述他们的传
递方式
C语言函数调用时参数的传递方式主要有以下几种:
1. 值传递:函数调用时,将实际参数的值复制给形式参数,函数内部对形式参数进行修改不会影响实际参数的值。

这是最常见的参数传递方式。

2. 引用传递:通过传递变量的指针作为参数,函数内部可以直接通过指针访问和修改实际参数的值。

这种方式可以实现在函数内部改变实参的值。

3. 地址传递:传递变量的地址作为参数,在函数内部通过指针来访问和修改实际参数的值。

和引用传递类似,通过地址传递也可以改变实参的值。

4. 数组传递:将数组的首地址作为参数传递给函数,函数内部可以通过指针来访问和修改数组的元素。

5. 结构体传递:将整个结构体作为参数传递给函数,在函数内部可以直接访问和修改结构体中的成员。

需要注意的是,C语言中的参数传递都是按值传递的,包括引
用传递和地址传递。

所谓按值传递,是指在函数调用时将实参的值复制给形参,函数内部对形参的操作不会影响到实参的值。

但是通过引用传递和地址传递,可以通过指针来访问和修改实参的值,使得函数可以改变实参的值。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
cout<<"利用引用传递数据后"<<endl<<"结构体存放内容"<<data.a<<" "<<(void *)&data.a<<endl;
cout<<" "<<data.b<<" "<<&data.b<<endl;
cout<<" "<<data.c<<" "<<&data.c<<endl<<endl;
cout<<" "<<data.b<<" "<<&data.b<<endl;
cout<<" "<<data.c<<" "<<&data.c<<endl<<endl;
//利用结构体传递数据
out_s(data);
//利用结构体指针传递数据
out_p(point);
//利用结构体引用传递数据
out_r(rdata);
{
arr[0].a='M';
arr[1].a='N';
}
void main()
{
struct A data={'h',2,3.3};
struct A *point=&data;
struct A &rdata=data;
struct A array[2]={{'X',23,45.44},{'Y',99,100.23}};
cout<<"结构体存放内容"<<s.a<<" "<<(void *)&s.a<<endl;
cout<<" "<<s.b<<" "<<&s.b<<endl;
cout<<" "<<s.c<<" "<<&s.c<<endl<<endl;
}
void out_p(struct A *p) //利用结构体指针传递数据
{
cout<<"利用指针传递数据,形参p内存地址"<<&p<<endl;
cout<<"形参p存放内容"<<p<<endl<<endl;
}
void out_r(struct A &r) //利用结构体引用传递数据
{
r.a='-';
r.b=0;
r.c=0;
}
void out_a(struct A arr[])
【程序源代码】
#include<iostream.h>
struct A//构建结构体,sizeof(A)=16
{
char a;
int b;
double c;
};
void out_s(struct A s) //利用结构体变量传递数据
{
cout<<"利用结构体传递数据形参s内存地址"<<&s<<endl;
out_a
数组传递
0x00401038
0x00401039
0x0040103A
0x0040103B
【运行结果】
(别名)
存放内容
0x0018FEB4
char
s.a
h
形参使用结构体,在内存开辟空间,用后释放,所以与之后形参指针在内存分配上有重合
0x00018FEB7
0x0018FEB8
int
s.b
2
0x0018FEB9
0x0018FEBA
0x0018FEBB
0x0018FEBC
cout<<" "<<array[0].c<<" "<<&array[0].c<<endl;
cout<<" "<<array[1].a<<" "<<(void *)&array[1].a<<endl;
cout<<" "<<array[1].b<<" "<<&array[1].b<<endl;
cout<<" "<<array[1].c<<" "<<&array[1].c<<endl<<endl;
//各函数地址
cout<<"变量传递,函数地址"<<out_s<<endl;
cout<<"指针传递,函数地址"<<out_p<<endl;
cout<<"引用传递,函数地址"<<out_r<<endl;
cout<<"数组传递,函数地址"<<out_a<<endl;
}
【内存分配】
形参
内存地址
类型
变量名称
0x0018FF12
0x0018FF13
0x0018FF14
int
array[0].b
23
0x0018FF15
0x0018FF16
0x0018FF17
0x0018FF18
double
array[0].c
45.44
0x0018FF19
0x0018FF1A
0x0018FF1B
0x0018FF1C
0x0018FF1D
array[1].c
100.23
0x0018FF29
0x0018FF2A
0x0018FF2B
0x0018FF2C
0x0018FF2D
0x0018FF2E
0x0018FF2F
0x0018FF30
0x0018FF31
0x0018FF32
0x0018FF33
0x0018FF34
struct A *
ponit
//利用结构体引用传递数据
out_a(array);
cout<<"利用数组传递数据后"<<endl<<"结构体存放内容"<<array[0].a<<" "<<(void *)&array[0].a<<endl;
cout<<" "<<array[0].b<<" "<<&array[0].b<<endl;
上一节课,我们知道了什么是结构体类型,以及结构体变量占据内存的大小。既然结构体是一个数据类型,那么,除了用它定义结构体变量之外,我们还可以用它来定义结构体数组、结构体引用与指针、结构体函数……其实,只要你懂得整型数组、整型变量的引用与指针、以及返回值为整型的函数等使用,就很容易理解结构体类型类似的用法。
0x0018FF3E
0x0018FF3F
0x0018FF40
double
data.c
3.3
0x0018FF41
0x0018FF42
0x0018FF43
0x0018FF44
函数
内存地址
类型
函数名称
存放内容
0x00401028
void
out_r
引用传递
0x00401029
0x0040102A
0x0040102B
0x0040102C
0x0040102D
void
out_p
指针传递
0x0040102E
0x0040102F
0x00401030
0x00401031
0x00401032
void
out_s
变量传递
0x00401033
0x00401034
0x00401035
0x00401036
0x00401037
void
cout<<"结构体data指针所在内存地址"<<&point<<endl;
cout<<"结构体data指针所存放内容"<<point<<endl;
cout<<"结构体data存放内容"<<data.a<<" "<<(void *)&data.a<<endl; //字符型变量输出内存地址一般要进行数据类型强制
0x0018FF38
0x0018FF35
0x0018FF36
相关文档
最新文档