C++ 关于C+中指针的函数范围+;(或C)

C++ 关于C+中指针的函数范围+;(或C),c++,function,pointers,scope,C++,Function,Pointers,Scope,我试图编写可移植代码,允许函数访问数组之类的变量,即使它只是一个值。其背后的思想是代码不会生成大小为1的数组,但如果数组是数组,我需要能够循环数组中的所有值。由于我无法使用sizeof(foo)来确定内存是否大于单个实例,因此sizeof(foo)/sizeof(int)可能会起作用,但它太麻烦,无法包含在主代码中。宏不会有帮助,因为如果我使用三元运算符,如我所期望的#define ARRAY_或_NOT(foo,type)(sizeof(foo)/sizeof(type)>1)?(foo):(

我试图编写可移植代码,允许函数访问数组之类的变量,即使它只是一个值。其背后的思想是代码不会生成大小为1的数组,但如果数组是数组,我需要能够循环数组中的所有值。由于我无法使用
sizeof(foo)
来确定内存是否大于单个实例,因此
sizeof(foo)/sizeof(int)
可能会起作用,但它太麻烦,无法包含在主代码中。宏不会有帮助,因为如果我使用三元运算符,如我所期望的
#define ARRAY_或_NOT(foo,type)(sizeof(foo)/sizeof(type)>1)?(foo):(&foo)
返回指针,以便通过索引进行访问。这个问题是编译器不喜欢指针和非指针之间类型的混合

所以我的第二次尝试是函数重载

int * convert(int value)
    {return &value;}
int * convert(int * value)
    {return value;}
我知道这是行不通的,因为第一个函数将返回该函数作用域中临时变量副本的地址。所以我的第三次尝试是

int * convert(int * value)
    {return value;}
int * convert(int ** value)
    {return *value;}
每次调用convert时,都要传递值的地址:
convert(&foo)
。 这应该是可行的,而且(我认为)它避免了返回临时函数作用域 地址。转换的结果可以通过索引访问。在受控for循环中,代码将平稳运行。程序将知道有多少元素是有价值的,但在for循环中运行所有内容要比不运行更快

那么,为什么我的第二段代码会产生“警告返回临时作用域blahblahblah”警告呢

更新:这里有主要的XY问题

基本上,我试图将所有代码包装在一个循环中,并访问变量中的每个值,每个循环迭代一个值。系统将知道该变量中有多少个值,但代码库太大,将所有内容包装到if/else中会很慢。因此,使用索引访问for循环中的某个值的方法是
intfoo=convert(&maybeArray)[counter]

另一个解决方案是使用重载运算符生成2个函数,这些函数基本上可以执行整个代码,而无需转换每个变量,但代码库非常大,这需要尽可能的可移植。引用
convert
将是我相信的未来证明。

在C中,只存在传递值。将指针传递给函数时,其地址将复制到函数参数。这仅仅意味着,如果
p
是调用函数的指针,那么函数调用

int x = 5;
int *p = &x;
int a = foo(p);   
用于函数定义

int foo(int *p1)
{
    return *p1*2;
}  
这意味着:

  • 将地址
    p
    点复制到参数
    p1
    ,即将
    p
    p1
    点复制到同一位置
  • 函数foo中对
    p1
    所指位置的任何更改都会反映到
    *p
    ,因为
    p
    p1
    指向同一位置。但是,如果在任何点
    p1
    指向另一个位置,则这并不意味着
    p
    也将指向该位置
    p
    p1
    是两个不同的指针
当您将一个指针传递给指针时,就像在第二个块的最后一个片段中一样

int * convert(int ** value)
{return *value;}  

如果将参数传递给
*value
后,该值变为指向不同的位置,则传递其地址的指针也将用该位置更新。在这种情况下,无需返回
*值
,但返回不会造成任何伤害

< P>你把这个标记为<代码> C++ >代码>,所以我假设你使用的是C++编译器。< /P> 你的问题有很多,所以我要简化一下。你想要一个C++函数<代码>转换(x)< /> >,将:

  • 如果
    x
    是数组,则返回第一个元素的地址
  • 如果
    x
    不是数组,则返回
    &x
  • (通常,您可能需要重新设计整个功能,
    convert
    似乎是一个非常奇怪的函数)

    模板
    自动转换(T&T)[N])->T*{
    return t;//让指针衰减在这里为我们工作
    }
    模板
    自动转换(T&T)->T*{
    返回&t;
    }
    
    <>和,在C++中,我从不使用sieOs我认为是数组的东西。这种模板技术是计算数组中元素数的更安全的方法

    另外,您是否希望拥有指针数组,并希望将单个指针视为指针的单个元素数组?如果是这样,那就小心踩。看起来像数组的东西实际上可能是指针,例如参数列表中的数组
    foo(int是真正的指针[5]){…}
    。有关更多信息,请参阅@MSalters的评论。用他的断言来捕捉任何惊喜可能是好的。如果您只是使用
    int
    ,那么不要在我的模板中使用
    typename t
    ,为了清晰起见,只需将其强制为
    int

    最后,也许您不应该将数组转换为指针,而是应该请求一个函数,将非数组转换为对单个元素数组的引用


    Update这里是一个演示如何使用
    convert
    convert\u end
    查找数组的开头和结尾,以迭代数组中的所有元素的示例;当然,非数组被视为一个元素的数组。

    注意,要确定某个元素是否是数组,更可靠的方法是
    ((char*)(foo)==(char*)&(foo))
    。您能发布带有警告的确切代码吗?我对第二段代码(编译为C++)没有任何要求。这是C还是C++问题?对于第三次尝试/第二个块不应该有警告。你能发布真实的信息和完整的例子吗?这看起来像
    template<typename T, size_t N>
    auto convert(  T (&t) [N] ) -> T* {
        return t; // just let pointer decay work for us here
    }
    template<typename T>
    auto convert( T &t) -> T* {
        return &t;
    }