[英]Can a temporary array of pointer be passed to a function in C?
在下面的代碼中,我想使用臨時指針數組調用函數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語言語法允許將指針的臨時數組傳遞給函數?
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 );
復合文字的剖析在於,它是用於為類型名稱的初始化對象提供類型名稱的語法。 它不是將強制轉換運算符應用於某種表達式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.