用C语言编写指针

时间:2014-01-28 23:56:40

标签: c pointers

我是C的新手,我正在编写一个非常基本的函数,它将整数指针作为参数。在函数内部,必须创建一个浮点指针。此函数必须将整数指针的值赋给float,然后返回float。这是我目前的代码:

float * function(const int *x)
{
    float *p = (float*)x;
    return p;
}

但是这会导致在运行时读取的错误:“free():无效指针:0x00007fffc0e6b734”。我只想说,我很困惑。您可以提供的任何见解将非常感谢!

2 个答案:

答案 0 :(得分:0)

成为C的新手,您熟悉scope of variables吗? (部分)变量作用域的简短版本是,如果你不做一些额外的东西,在函数中创建的变量只存在于该函数内。为什么这对你很重要:如果你返回一个指向你在一个函数内部创建的变量的指针(没有做那些额外的事情),那么指针将指向一个内存区域,该区域可能包含也可能不包含你赋给它的值。做你想做的事的一种方法是:

float *makefloat(int *x) {

//  static keyword tells C to keep this variable after function exits
    static float f;

//  the next statement working from right to left does the following
//  get value of pointer to int (x) by dereferencing:   *x
//  change that int value to a float with a cast:       (float)
//  assign that value to the static float we created:   f =
    f = (float) *x; 
//  make pointer to float from static variable:         &f
    return &f;
}

一般来说,我似乎看到更多函数接受指向要修改的变量的指针,然后在该函数中创建新值并将其分配给指针引用的内存区域。因为该内存区域存在于函数范围之外,所以不必担心范围和静态变量。关于静态变量的另一个很酷的事情是,下次调用该函数时,静态变量具有与函数上次退出时相同的值。在Wikipedia上解释。

*&的良好解释:Pointers in C: when to use the ampersand and the asterisk

答案 1 :(得分:0)

您的函数仅执行指针转换。表单的函数调用

q = function(p); /* p is a "const int *" pointer,
                    q is assignment comaptible with "float *". */

可以用表达式替换:

q = (float *) p;

本身,这没有任何伤害。问题出在您的计划的其他地方。

请注意,大多数类型惩罚,例如通过指针使用类型int的表达式访问类型float的对象,是C语言中的未定义行为。这不是在示例代码中进行的,但是事情朝这个方向发展;指针可能正在准备进行打字。

请注意intfloat的大小不一定相同;这不是唯一的考虑因素。在这样的代码中:

int i = 42;
/* now treat i as a float and modify it sneakily */
*((float *) &i) = 3.14;

printf("i = %d\n", i);

printf的输出仍然可以是42.优化编译器可以将i放入机器寄存器,而可以在作为“后备存储”的内存位置执行偷偷摸摸的分配“对于i,所以i显示为未更改,因为printf调用使用了寄存器缓存的副本。编译器不需要考虑对类型float指定的对象的修改可能会影响类型i的对象的值(即使它们具有相同的大小,因此没有通过转让完成的附带损害,如覆盖其他物品)。

在现实世界中,有时需要编写一个操作浮点对象的代码,就好像它们是整数一样:通常为unsigned int个整数,以获取对float的按位表示的访问权限。完成此操作后,您必须使用联合,或者可能使用编译器特定的功能,例如GCC的-fno-strict-aliasing选项,这会导致编译器在类型惩罚时更加谨慎地进行优化。在这种代码中,您确保所有假设都是关于类型大小的保证,使用#ifdef - s用于不同平台,可能基于从运行配置脚本中提取的值来检测平台功能。 / p>

毋庸置疑,这不是一个在初学者阶段学习C的好方法。