【问题标题】:Can a temporary array of pointer be passed to a function in C?可以将临时指针数组传递给 C 中的函数吗?
【发布时间】:2018-04-08 07:54:31
【问题描述】:

在下面的代码中,我想用一个临时的指针数组调用函数f()f2(),如第 33 行和第 39 行...

#include <stdio.h>

void f( const char** const p, size_t num )
{
  size_t i;
  for ( i = 0; i < num; ++i )
  {
    printf( "%s\n", p[ i ] );
  }
}

void f2( const char* const p[2] )
{
  size_t i;
  for ( i = 0; i < 2; ++i )
  {
    printf( "%s\n", p[ i ] );
  }
}

void withPtrArray()
{
  const char* tmp[] = { "hello", "world" };
  const char** p;

  // This compiles/runs fine:
  f( tmp, sizeof tmp / sizeof( const char* ) );

  // This also compiles/runs fine:
  f( ( p = tmp ), 2 );

  // This does not compile - I'm not clear why.
  f( ( { "hello", "world" } ), 2 );

  // My last hope: I thought a function that explicitly took a pointer array:
  // This works...
  f2( tmp );
  // ...but this does not:
  f2( { "hello", "world" } );
}


void g( const char* const p )
{
  printf( "%s\n", p );
}

// Analog to f2()
void g2( const char p[12] )
{
  printf( "%s\n", p );
}

// These analogs with an array of chars work fine.
void withPtr()
{
  const char tmp[] = "hello world";
  const char* p = tmp;

  g( tmp );

  g( ( p = tmp ) );

  g( ( "hello world" ) );

  g2( tmp );

  g2( "hello world" );
}

int main( int argc, char* argv[] )
{
  withPtrArray();
  withPtr();
  return 0;
}

...但是那些行编译失败...

prog.c: In function ‘withPtrArray’:
prog.c:33:17: warning: left-hand operand of comma expression has no effect [-Wunused-value]
   f( ( { "hello", "world" } ), 2 );
                 ^
prog.c:33:27: error: expected ‘;’ before ‘}’ token
   f( ( { "hello", "world" } ), 2 );
                           ^
prog.c:33:6: warning: passing argument 1 of ‘f’ from incompatible pointer type [-Wincompatible-pointer-types]
   f( ( { "hello", "world" } ), 2 );
      ^
prog.c:3:6: note: expected ‘const char ** const’ but argument is of type ‘char *’
 void f( const char** const p, size_t num )
      ^
prog.c:39:7: error: expected expression before ‘{’ token
   f2( { "hello", "world" } );
       ^

我从 C 迁移到 C++ 已经有几年了,但我不认为这是 C 和 C++ 之间语法差异的问题。

是否有允许将临时指针数组传递给函数的 C 语法?

【问题讨论】:

  • @EugeneSh。 - 美丽的! f( (const char*[]){ "hello", "world" }, 2 ); 是需要的秘方。如果您想要积分,您应该发布作为答案。谢谢!

标签: c arrays pointers temporary


【解决方案1】:

f( ( { "hello", "world" } ), 2 ) 的问题在于:函数的参数必须是表达式。但是,其他表达式的花括号列表本身并不是一个表达式。

也许您错误地将{ "hello", "world" } 视为可能具有“2 个字符数组的数组”类型的表达式。但事实并非如此。您可能已经注意到{ "hello" }; 也不是有效代码:每个表达式都可以通过在其后面加上; 来转换为语句,因此{"hello"} 不能是表达式。

以下代码也不起作用:

char *c[2];
c = { "hello", "world" };

甚至:

int y;
y = { 5 };

在这两种情况下,赋值运算符后面必须跟一个表达式;但是没有表达式的语法包含大括号内的内容。

花括号列表只能作为声明的初始值设定项出现,或者出现在复合文字中。大括号表示存在一个初始值设定项列表。

声明的结构是类型名和声明符,后跟= 符号(它不是赋值运算符,因为这不是表达式),然后是初始化器。初始化器可以是表达式,也可以是初始化器的花括号列表。这种声明的含义是,每个初始化器都作为声明中声明的对象之一的初始值。


在您的代码中,您可以使用复合文字:

f( (const char *[2]){ "hello", "world" }, 2 );

复合字面量的解剖结构是,它是一种为该类型的对象提供带有初始化器的类型名的语法;它不是应用于某种表达式的强制转换运算符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    相关资源
    最近更新 更多