结构体:
感觉可以理解为一个类,后面使用的时候实例化。
一个小小的案例
1 |
|
另一个版本
1 |
|
另一个版本的修改版本:
1 |
|
其实就是先规定好Student里有些什么数据,然后Student s1实例化,通过initStudent函数来赋值,printStudent来打印,这里直接用的是指针,准确来说,如果是指针的话,会修改里面结构体里的值,但是如果用的是值传递的话则不会,但是这个无所谓,因为我们这里实例化了一个对象了呀。
我们可以参考一下chatgpt的回答,总的来说就是一个局部变量的问题
当你使用值传递将结构体 Student 传递给函数 initStudent 时,函数内部实际上操作的是这个结构体的一个副本,而不是原始的结构体实例。这意味着在函数 initStudent 中对结构体 s 的任何修改都只会影响这个副本,一旦函数执行完毕,这个副本就被销毁,原始结构体 s1 的内容保持不变。下面我来详细解释这个过程:
值传递的工作原理
- 创建副本:在你调用
initStudent(s1, "Alice", 20, 92.5);时,s1的每个字段(name,age,score)都被复制到函数的参数s中。这个参数s是函数的局部变量,它和s1占用不同的内存空间。 - 局部作用域:由于
s是函数的局部变量,所以在函数完成执行后,这个局部变量就会被销毁。函数中对s所做的任何修改(比如设置名字、年龄和分数)都仅限于这个局部副本,而不会反映到原始的s1上。
为什么不生效
因为函数 initStudent 只是修改了它自己的局部副本 s,这个副本在函数结束时消失了,原始的结构体 s1 并未被修改。这就是为什么你看不到预期的改变,原始的 s1 依然保持调用函数前的状态。
如何解决
要想通过函数修改结构体的内容并让这些修改在函数外部也有效,你需要使用指针传递,而不是值传递。通过指针传递,你可以直接访问并修改原始结构体实例的内存地址,而不是操作它的副本。
修改后的函数使用指针
1 | cCopy codevoid initStudent(Student *s, const char *name, int age, float score) { |
调用时需要传递地址:
1 | cCopy code |
总结
这个例子很好地说明了值传递与引用(指针)传递之间的区别。值传递适用于不需要修改原始数据或者只需要一个数据副本的情况。引用传递则适用于需要直接修改原始数据的场合。希望这能帮助你更好地理解这两种参数传递方式的差异!如果你还有其他问题或需要进一步的解释,随时欢迎提问。
对于函数内的变量要不要加&,可以这么理解,如果要修改原来的东西的话,就得加上,因为要把实际的位置给他,这样才能修改里面的值,如果说只是一个拿来计数或者说并修改的话,那肯定是不加啦。
解释一下这行代码吧 LNode* node = (LNode*)malloc(sizeof(LNode)); 为什么要用(LNode*)呢
ChatGPT
ChatGPT
在C++(或C)中,这行代码 LNode* node = (LNode*)malloc(sizeof(LNode)); 的目的是为一个 LNode 类型的结构体分配内存。这里的细节包含几个关键部分,让我逐一解释:
malloc函数
malloc函数用于在堆上动态分配指定大小的内存块。它是C语言标准库提供的函数,也可以在C++中使用。malloc的参数是你需要分配的字节数。sizeof(LNode)计算LNode结构体所需的内存大小,确保分配足够的空间来存储一个LNode结构体。malloc返回的是一个void*类型的指针,这意味着它指向一个未指定类型的内存块。
类型转换 (LNode*)
- 在C++中,指针类型需要明确。因为
malloc返回的是void*类型,所以它指向的内存没有具体的类型。 LNode*是一个指向LNode类型的指针,指明了这块内存将被作为LNode类型来访问。(LNode*)是一个强制类型转换,将void*转换为LNode*。这样做是为了告诉编译器:我们分配的内存将被当作LNode结构体来使用。
为什么需要类型转换
- 在C语言中,
void*类型的指针可以自动转换为任何其他类型的指针,因此经常可以看到没有显式转换的malloc调用。 - 然而,在C++中,
void*到其他类型的指针的转换不是自动的,必须显式进行。如果不进行显式转换,编译器会报错,因为它不能确定void*指针的具体类型。
代码示例
1 | cppCopy codeLNode* node = (LNode*)malloc(sizeof(LNode)); // 分配内存并转换类型 |
这行代码使用 (LNode*) 是为了确保编译器理解我们如何意图使用这块内存,这是一种确保类型安全的做法,尽管它在现代C++编程中通常不推荐使用 malloc,而是推荐使用 new 操作符,因为 new 自动处理类型问题并调用构造函数。
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License .