区块链技术博客
www.b2bchain.cn

C语言的参数传递求职学习资料

D0b2wT.gif

本文介绍了C语言的参数传递求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

C语言所有的参数传递都是值传递

概念:形参和实参

形参:形式参数

实参:实际参数

void add(int a, int b);  int main() {     add(1, 2); }

以上代码中,a和b是形参,1和2为实参

传递基础类型参数

基础类型:int、float、double、char等

  1. 形参和实参具有不同的地址
  2. 形参和实参值相同
  3. 改变形参值只影响形参,不影响实参。

示例如下:

#include <stdio.h>  void printInt(int value) {     printf("printInt 值:%d 地址:%pn", value, &value);     value = 20;     printf("printInt 值:%d 地址:%pn", value, &value); }   int main(void) {      int ivalue = 10;      printf("main int值:%d 地址:%pn", ivalue, &ivalue);     printInt(ivalue);     printf("main int值:%d 地址:%pn", ivalue, &ivalue);      return 0; }  /* 输出 main int值:10 地址:0x7fffbcdc532c printInt 值:10 地址:0x7fffbcdc530c printInt 值:20 地址:0x7fffbcdc530c main int值:10 地址:0x7fffbcdc532c */

结论

  1. 输出value的值和地址,实参地址为0x7fffbcdc532c, 形参value地址为0x7fffbcdc530c, 两者不相等
  2. 虽然地址不同,但是实参和形参值均为10,两者值相同
  3. 改变形参的值为20,实参输出仍为10
  4. 同理可以继续校验floatdoublechar等基础类型也可以得到一样的结论。

传递struct

struct Person {     int age; };  void printStruct(struct Person person) {     printf("printStruct 值:%d 地址:%pn", person.age, &person);     person.age = 30;     printf("printStruct 值:%d 地址:%pn", person.age, &person); }   int main(void) {      struct Person person = { 20 };     printf("main Struct 值:%d 地址:%pn", person.age, &person);     printStruct(person);     printf("main Struct 值:%d 地址:%pn", person.age, &person); } /* 输出: main Struct 值:20 地址:0x7fff475834dc printStruct 值:20 地址:0x7fff475834bc printStruct 值:30 地址:0x7fff475834bc main Struct 值:20 地址:0x7fff475834dc */

观察程序输出,形参和实参具有不同的地址(注意dc和bc的区别),改变形参不影响实参的age属性。

传递数组和指针

#include <stdio.h>  void printArray(int arr[5]) {     printf("printArray 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      arr[2] = 10;      printf("printArray 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr); }  void printArray1(int *arr, size_t count) {     printf("printArray1 值:");     for(int i = 0; i < count; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      arr[2] = 100;      printf("printArray1 值:");     for(int i = 0; i < count; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr); }   int main(void) {      int arr[] = {1, 2, 3, 4, 5};      // 第一次输出     printf("main Array 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      printArray(arr);      // 再次输出     printf("main Array 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      printArray1(arr, 5);      // 再次输出     printf("main Array 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      return 0; }  /* main Array 值:1 2 3 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa0506220 printArray 值:1 2 3 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 printArray 值:1 2 10 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 main Array 值:1 2 10 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa0506220 printArray1 值:1 2 10 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 printArray1 值:1 2 100 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 main Array 值:1 2 100 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa0506220 */

分析:

1. 最重要的结论,函数内修改指针指向的值实际上修改的就是实参。
2. 参数传递的值就是指针(实际上是指针指向的地址),函数新建了一个int *的指针arr, 其地址为0x7fffa05061f8, 它存储的值是数组的第一个元素的地址0x7fffa0506220

检验

参数传递本质上是声明了一个新的变量,然后将值传递,区别在于指针参数传递的是指针地址,而基础类型传递的值。

int main(void) {       char c0 = 'h';     char c1, c2;     c1 = c0;     c2 = c0;     printf("值:%c c0的地址:%pn", c0, &c0);     printf("值:%c c1的地址:%pn", c1, &c1);     printf("值:%c c2的地址:%pn", c2, &c2);      int arr[] = {1, 2, 3, 4, 5};      int *pt1;     int *pt2;     pt1 = arr;     pt2 = arr;      printf("地址:%p arr的地址:%p %pn", arr, &arr, &arr[0]);     printf("地址:%p pt1的地址:%pn", pt1, &pt1);     printf("地址:%p pt2的地址:%pn", pt2, &pt2);      return 0; }  /* 输出: 值:h c0的地址:0x7ffee3f8b79b 值:h c1的地址:0x7ffee3f8b79a 值:h c2的地址:0x7ffee3f8b799 地址:0x7ffee3f8b7a0 arr的地址:0x7ffee3f8b7a0 0x7ffee3f8b7a0 地址:0x7ffee3f8b7a0 pt1的地址:0x7ffee3f8b790 地址:0x7ffee3f8b7a0 pt2的地址:0x7ffee3f8b788 */

总结

C的参数传递实质上都是值传递,区别在于
对于基础类型,值就是数据本身,形参存储了原数据的一份copy, 所以对形参的修改不会影响原数据。
对于指针类型,值就是指针 ,但是由于不论实参还是新创建的指针变量,其存储的值都是原数据的地址,所以在这个地址上所有的修改都会影响原数据。

疑问?

为什么printArray和printArray1中形参的地址会相同?

尝试换函数也会得到同样的结果, 猜测可能是编译器优化结果。有知道的朋友可以留言

C语言所有的参数传递都是值传递

概念:形参和实参

形参:形式参数

实参:实际参数

void add(int a, int b);  int main() {     add(1, 2); }

以上代码中,a和b是形参,1和2为实参

传递基础类型参数

基础类型:int、float、double、char等

  1. 形参和实参具有不同的地址
  2. 形参和实参值相同
  3. 改变形参值只影响形参,不影响实参。

示例如下:

#include <stdio.h>  void printInt(int value) {     printf("printInt 值:%d 地址:%pn", value, &value);     value = 20;     printf("printInt 值:%d 地址:%pn", value, &value); }   int main(void) {      int ivalue = 10;      printf("main int值:%d 地址:%pn", ivalue, &ivalue);     printInt(ivalue);     printf("main int值:%d 地址:%pn", ivalue, &ivalue);      return 0; }  /* 输出 main int值:10 地址:0x7fffbcdc532c printInt 值:10 地址:0x7fffbcdc530c printInt 值:20 地址:0x7fffbcdc530c main int值:10 地址:0x7fffbcdc532c */

结论

  1. 输出value的值和地址,实参地址为0x7fffbcdc532c, 形参value地址为0x7fffbcdc530c, 两者不相等
  2. 虽然地址不同,但是实参和形参值均为10,两者值相同
  3. 改变形参的值为20,实参输出仍为10
  4. 同理可以继续校验floatdoublechar等基础类型也可以得到一样的结论。

传递struct

struct Person {     int age; };  void printStruct(struct Person person) {     printf("printStruct 值:%d 地址:%pn", person.age, &person);     person.age = 30;     printf("printStruct 值:%d 地址:%pn", person.age, &person); }   int main(void) {      struct Person person = { 20 };     printf("main Struct 值:%d 地址:%pn", person.age, &person);     printStruct(person);     printf("main Struct 值:%d 地址:%pn", person.age, &person); } /* 输出: main Struct 值:20 地址:0x7fff475834dc printStruct 值:20 地址:0x7fff475834bc printStruct 值:30 地址:0x7fff475834bc main Struct 值:20 地址:0x7fff475834dc */

观察程序输出,形参和实参具有不同的地址(注意dc和bc的区别),改变形参不影响实参的age属性。

传递数组和指针

#include <stdio.h>  void printArray(int arr[5]) {     printf("printArray 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      arr[2] = 10;      printf("printArray 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr); }  void printArray1(int *arr, size_t count) {     printf("printArray1 值:");     for(int i = 0; i < count; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      arr[2] = 100;      printf("printArray1 值:");     for(int i = 0; i < count; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr); }   int main(void) {      int arr[] = {1, 2, 3, 4, 5};      // 第一次输出     printf("main Array 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      printArray(arr);      // 再次输出     printf("main Array 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      printArray1(arr, 5);      // 再次输出     printf("main Array 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      return 0; }  /* main Array 值:1 2 3 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa0506220 printArray 值:1 2 3 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 printArray 值:1 2 10 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 main Array 值:1 2 10 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa0506220 printArray1 值:1 2 10 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 printArray1 值:1 2 100 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 main Array 值:1 2 100 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa0506220 */

分析:

1. 最重要的结论,函数内修改指针指向的值实际上修改的就是实参。
2. 参数传递的值就是指针(实际上是指针指向的地址),函数新建了一个int *的指针arr, 其地址为0x7fffa05061f8, 它存储的值是数组的第一个元素的地址0x7fffa0506220

检验

参数传递本质上是声明了一个新的变量,然后将值传递,区别在于指针参数传递的是指针地址,而基础类型传递的值。

int main(void) {       char c0 = 'h';     char c1, c2;     c1 = c0;     c2 = c0;     printf("值:%c c0的地址:%pn", c0, &c0);     printf("值:%c c1的地址:%pn", c1, &c1);     printf("值:%c c2的地址:%pn", c2, &c2);      int arr[] = {1, 2, 3, 4, 5};      int *pt1;     int *pt2;     pt1 = arr;     pt2 = arr;      printf("地址:%p arr的地址:%p %pn", arr, &arr, &arr[0]);     printf("地址:%p pt1的地址:%pn", pt1, &pt1);     printf("地址:%p pt2的地址:%pn", pt2, &pt2);      return 0; }  /* 输出: 值:h c0的地址:0x7ffee3f8b79b 值:h c1的地址:0x7ffee3f8b79a 值:h c2的地址:0x7ffee3f8b799 地址:0x7ffee3f8b7a0 arr的地址:0x7ffee3f8b7a0 0x7ffee3f8b7a0 地址:0x7ffee3f8b7a0 pt1的地址:0x7ffee3f8b790 地址:0x7ffee3f8b7a0 pt2的地址:0x7ffee3f8b788 */

总结

C的参数传递实质上都是值传递,区别在于
对于基础类型,值就是数据本身,形参存储了原数据的一份copy, 所以对形参的修改不会影响原数据。
对于指针类型,值就是指针 ,但是由于不论实参还是新创建的指针变量,其存储的值都是原数据的地址,所以在这个地址上所有的修改都会影响原数据。

疑问?

为什么printArray和printArray1中形参的地址会相同?

尝试换函数也会得到同样的结果, 猜测可能是编译器优化结果。有知道的朋友可以留言

C语言所有的参数传递都是值传递

概念:形参和实参

形参:形式参数

实参:实际参数

void add(int a, int b);  int main() {     add(1, 2); }

以上代码中,a和b是形参,1和2为实参

传递基础类型参数

基础类型:int、float、double、char等

  1. 形参和实参具有不同的地址
  2. 形参和实参值相同
  3. 改变形参值只影响形参,不影响实参。

示例如下:

#include <stdio.h>  void printInt(int value) {     printf("printInt 值:%d 地址:%pn", value, &value);     value = 20;     printf("printInt 值:%d 地址:%pn", value, &value); }   int main(void) {      int ivalue = 10;      printf("main int值:%d 地址:%pn", ivalue, &ivalue);     printInt(ivalue);     printf("main int值:%d 地址:%pn", ivalue, &ivalue);      return 0; }  /* 输出 main int值:10 地址:0x7fffbcdc532c printInt 值:10 地址:0x7fffbcdc530c printInt 值:20 地址:0x7fffbcdc530c main int值:10 地址:0x7fffbcdc532c */

结论

  1. 输出value的值和地址,实参地址为0x7fffbcdc532c, 形参value地址为0x7fffbcdc530c, 两者不相等
  2. 虽然地址不同,但是实参和形参值均为10,两者值相同
  3. 改变形参的值为20,实参输出仍为10
  4. 同理可以继续校验floatdoublechar等基础类型也可以得到一样的结论。

传递struct

struct Person {     int age; };  void printStruct(struct Person person) {     printf("printStruct 值:%d 地址:%pn", person.age, &person);     person.age = 30;     printf("printStruct 值:%d 地址:%pn", person.age, &person); }   int main(void) {      struct Person person = { 20 };     printf("main Struct 值:%d 地址:%pn", person.age, &person);     printStruct(person);     printf("main Struct 值:%d 地址:%pn", person.age, &person); } /* 输出: main Struct 值:20 地址:0x7fff475834dc printStruct 值:20 地址:0x7fff475834bc printStruct 值:30 地址:0x7fff475834bc main Struct 值:20 地址:0x7fff475834dc */

观察程序输出,形参和实参具有不同的地址(注意dc和bc的区别),改变形参不影响实参的age属性。

传递数组和指针

#include <stdio.h>  void printArray(int arr[5]) {     printf("printArray 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      arr[2] = 10;      printf("printArray 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr); }  void printArray1(int *arr, size_t count) {     printf("printArray1 值:");     for(int i = 0; i < count; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      arr[2] = 100;      printf("printArray1 值:");     for(int i = 0; i < count; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr); }   int main(void) {      int arr[] = {1, 2, 3, 4, 5};      // 第一次输出     printf("main Array 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      printArray(arr);      // 再次输出     printf("main Array 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      printArray1(arr, 5);      // 再次输出     printf("main Array 值:");     for(int i = 0; i < 5; i++) {         printf("%d ", arr[i]);     }     printf("地址:%p arr的地址:%pn", arr, &arr);      return 0; }  /* main Array 值:1 2 3 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa0506220 printArray 值:1 2 3 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 printArray 值:1 2 10 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 main Array 值:1 2 10 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa0506220 printArray1 值:1 2 10 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 printArray1 值:1 2 100 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa05061f8 main Array 值:1 2 100 4 5 地址:0x7fffa0506220 arr的地址:0x7fffa0506220 */

分析:

1. 最重要的结论,函数内修改指针指向的值实际上修改的就是实参。
2. 参数传递的值就是指针(实际上是指针指向的地址),函数新建了一个int *的指针arr, 其地址为0x7fffa05061f8, 它存储的值是数组的第一个元素的地址0x7fffa0506220

检验

参数传递本质上是声明了一个新的变量,然后将值传递,区别在于指针参数传递的是指针地址,而基础类型传递的值。

int main(void) {       char c0 = 'h';     char c1, c2;     c1 = c0;     c2 = c0;     printf("值:%c c0的地址:%pn", c0, &c0);     printf("值:%c c1的地址:%pn", c1, &c1);     printf("值:%c c2的地址:%pn", c2, &c2);      int arr[] = {1, 2, 3, 4, 5};      int *pt1;     int *pt2;     pt1 = arr;     pt2 = arr;      printf("地址:%p arr的地址:%p %pn", arr, &arr, &arr[0]);     printf("地址:%p pt1的地址:%pn", pt1, &pt1);     printf("地址:%p pt2的地址:%pn", pt2, &pt2);      return 0; }  /* 输出: 值:h c0的地址:0x7ffee3f8b79b 值:h c1的地址:0x7ffee3f8b79a 值:h c2的地址:0x7ffee3f8b799 地址:0x7ffee3f8b7a0 arr的地址:0x7ffee3f8b7a0 0x7ffee3f8b7a0 地址:0x7ffee3f8b7a0 pt1的地址:0x7ffee3f8b790 地址:0x7ffee3f8b7a0 pt2的地址:0x7ffee3f8b788 */

总结

C的参数传递实质上都是值传递,区别在于
对于基础类型,值就是数据本身,形参存储了原数据的一份copy, 所以对形参的修改不会影响原数据。
对于指针类型,值就是指针 ,但是由于不论实参还是新创建的指针变量,其存储的值都是原数据的地址,所以在这个地址上所有的修改都会影响原数据。

疑问?

为什么printArray和printArray1中形参的地址会相同?

尝试换函数也会得到同样的结果, 猜测可能是编译器优化结果。有知道的朋友可以留言

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » C语言的参数传递求职学习资料
分享到: 更多 (0)
D0b2wT.gif

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们