整数数组与c ++中指向整数的指针

时间:2009-07-15 18:41:05

标签: c++ arrays pointers

如果我有int x[10]int *y,我怎么能区分这两者?

我有两个想法:

  
      
  1. sizeof()不同。

  2.   
  3. & x有不同的类型--- int (*p)[10] = &x有效,但不是int **q = &x

  4.   

还有其他人吗?

在某些模板库代码中,我需要确定指针是“实际”指针还是从数组中退化。我不能查看源代码,因为在我编写库之前库用户不存在。 ...我可以通过重写代码解决这个问题,所以现在这只是一个理论上的练习。

6 个答案:

答案 0 :(得分:5)

没有通用方法 - 您已经知道了类型,因为您刚刚声明了对象,或者类型已经衰减到指针并且已经丢失。请通过区分它们来解释您试图解决的问题。

答案 1 :(得分:2)

sizeof的想法不是很好,因为如果数组恰好有一个元素,并且元素类型碰巧与指针大小相同,那么它的大小将与大小相同指针。

类型匹配方法看起来更有前景,并且可能被用于选择模板专业化(如果这就是你要做的)。

答案 2 :(得分:2)

假设您没有尝试为在函数范围声明的类型执行此操作:

struct yes { char pad; };
struct no { yes pad[2]; };

template <typename T, size_t N> yes is_array_test(T (&arr)[N]);
no is_array_test(...);

#define IS_ARRAY(x) (sizeof(is_array_test(x))==sizeof(yes))

答案 3 :(得分:0)

int x [10]将在它被调用的地方总是分配在堆栈上。 x值永远不会改变。

int * y只是声明一个指向内存的指针,指针值可以随时更改而不受任何限制。

int * y可以有任意值。意思是,它可以指向堆栈分配的Memoryor堆分配的内存。从技术上讲,它也可以指向无效的内存,但这没有任何意义。

int x [10] guarntee你总是指向一个有效的内存,你不必担心内存释放。

使用int * y时,你必须担心它所指向的内存。

另外请记住,你的porgram动态分配内存的次数越多,它就会暴露于错误,泄漏,性能问题,分配\解除分配和许多其他类型的问题。

答案 4 :(得分:0)

它们是不同的类型。

你如何区分int32和uint32,或者uint32和char [4]?

正确的思考方式是它们相似的唯一方法是在某些上下文(包括数组索引!)中,数组会提升为指针。

答案 5 :(得分:0)

我刚尝试使用g ++ 4.5 C ++ 0x模式中的char数组,它不会让我同时定义

template <typename T>void moresilly(const T v[],const char *description)

AND

template <typename T>void moresilly(const T *v,const char *description)

它声称两者都是同一类型。

我有一个功能:

template <typename T>void silly(const T & v,const char *description)
{
    cout<<"size of "<<description<<" is "<< sizeof(T)<<endl;
    moresilly(v,description);
}

如果传递正确获取数组的大小,如果传递则正确获取指针的大小,但我不能使用moresilly来区分指针和数组,所以我不能告诉4字符数组从指针到n个字符。

在T [1],T [2],T [3]等上有模板可能有用,但是已经有帖子说不同的编译器处理那个(或类似的情况)不同而且gnu更喜欢C ++ 11中的指针匹配。

......稍后补充: 经过一些实验,我发现了一些适用于g ++ 4.5的东西

template <typename T,size_t L>void moresilly(const T (&v)[L],const char *description)
{
    cout<<description<<" is an array"<<endl;
}
template <typename T>void moresilly(const T *v,const char *description)
{
    cout<<description<<" is a pointer"<<endl;
}
template <typename T>void moresilly(const T v,const char *description)
{
    cout<<description<<" is a raw value"<<endl;
}
template <typename T>void silly(const T & v,const char *description)
{
    cout<<"size of "<<description<<" is "<< sizeof(T)<<endl;
    moresilly(v,description);
}

以下工作正常

    silly("12345","immediate string of 5 characters plus zero");
    silly((const char *)"12345","immediate constant char pointer of 5 characters plus zero");
    char testarray[]="abcdef";
    silly(testarray,"char array of 6 characters plus zero");
const char testarray2[]="abcdefg";
silly(testarray2,"const char array of 7 characters plus zero");

请注意,如果第一个函数定义为“const T v [L]”而不是“const T(&amp; v)[L]”,则它不起作用,从不匹配任何内容。

所以我解决了你的问题,但是不要指望这个在其他版本的编译器中工作,包括未来的版本。这就是我讨厌c ++的原因。不知何故,语言的定义是如此不清楚,编译器充满了不稳定的边缘情况。

这是一个有用的技巧,我可以使用它。