day3 函数的定义和调用,练习编写简单的程序(记录2)

一、值传递、指针传递、引用传递

值传递:

在值传递中,函数的形参是由实参的副本初始化的,也就是说,函数内部操作的是实参的一个拷贝。值传递适用于传递简单数据类型(如整数、浮点数、字符等)以及小型结构体等,可以避免意外的修改和副作用,但代价是需要进行大量的拷贝操作,可能会影响程序性能。

指针传递:

在指针传递中,函数的形参是指向实参的指针,因此函数内部操作的是实参本身,可以避免拷贝操作,提高程序性能。指针传递适用于传递大型数据类型(如数组、结构体等),但需要注意指针是否为空或无效等问题,以及指针所指向的数据是否被修改的风险。

引用传递:

在引用传递中,函数的形参是实参的别名,它们共享同一块内存地址,因此函数内部操作的是实参本身,而不是副本或指针。引用传递适用于传递大型数据类型,可以避免拷贝和修改的风险,但需要注意引用的有效性和作用域。

二、指针传递和引用传递:如何选择

在C语言中,指针传递和引用传递都是常见的传递方式,各有其优缺点,具体使用时需要根据实际情况来选择。

指针传递和引用传递的最大区别在于形参的声明方式。在指针传递中,形参是一个指针类型,需要使用*来解引用;而在引用传递中,形参是一个引用类型,不需要使用*来解引用。两种传递方式都可以在函数内部对实参进行修改,都可以避免拷贝操作,提高程序性能。

一般来说,如果需要在函数内部修改实参的值,并且实参是一个简单数据类型(如整数、浮点数、字符等),那么建议使用指针传递。因为引用传递只适用于C++中的引用类型,在C语言中则需要通过指针来实现类似的效果。

如果需要传递大型数据类型(如结构体、数组等)或多个参数,可以使用指针传递或引用传递。但需要注意,使用指针传递时需要确保指针的有效性和安全性,避免非法访问或悬垂指针等问题;而使用引用传递时需要注意引用的作用域和生命周期,以及是否会对源数据造成修改等问题。

综上所述,选择使用指针传递或引用传递,需要根据实际情况进行权衡和选择。如果不确定应该使用哪种传递方式,可以根据数据类型、程序安全性、代码清晰度等因素来考虑,并进行适当的试验和测试,以达到最优的设计效果。

值传递适用于传递简单数据类型和不需要修改实参的函数;指针传递适用于传递数组、结构体等较大的数据类型,或者需要修改实参的函数;引用传递适用于传递较大的数据类型,并且需要在函数内部修改实参的值。总之,在选择传递方式时需要考虑到效率、安全性和代码的可读性等因素,以确保程序的正确性和稳定性。

非法访问或悬垂指针定义

非法访问或悬垂指针是指试图访问一个已经被释放或者未被正确初始化的指针所指向的内存,这样的操作通常会导致程序崩溃、数据损坏等严重问题。

非法访问指针通常发生在以下几种情况中:

指针未被正确初始化:在定义指针时没有初始化它的值,或者采用不可预期的值来初始化,这样的指针可能指向了一个随机的地址。如果尝试使用这样的指针访问内存,很可能会读取到错误的数据或者写入到错误的地址,导致程序运行异常。

指针越界:如果指针超出了它指向内存块的边界范围,也会导致访问非法内存。例如,在使用指针访问数组元素时,如果指针的偏移量超过了数组的长度,则访问就越界了。

释放指针后继续使用:如果在释放完指针所指向的内存之后,仍然继续使用这个指针,这样的操作就是非法的。因为已经释放的内存可能已经被其他程序或系统调用使用,如果继续使用这样的指针,就会导致数据损坏或非法访问。

悬垂指针指的是已经被释放的指针,这类指针虽然不再指向有效的内存地址,但是程序中仍然可能对其进行引用,导致非法访问、数据损坏等问题。避免悬垂指针的方法是要确保在释放指针之后,立即将指针设为 NULL,这样就可以避免对已经无效的指针进行误用。

为了避免非法访问和悬垂指针的问题,需要在程序设计和实现过程中严格控制指针的使用,并进行错误检查和处理。建议在定义指针时进行初始化,避免采用随机的、未定义的值。在使用指针访问内存之前,需要先检查指针是否为空或有效,避免越界或非法访问。在释放指针所指向内存之后,需要立即将指针设为 NULL,避免悬垂指针的出现。

posted @ 2023-03-31 18:02  share0956  阅读(50)  评论(0编辑  收藏  举报