为什么这段代码会出现“表达式语法”错误?

时间:2013-07-27 18:29:26

标签: c++

为什么我会收到错误

Expression Syntax

在下面代码的m[0]=行上?

struct menu{
    int code;
    char name[30];
}m[5];

int main() {
   clrscr();
   m[0]={1,"MAGGI"}; //try to check whether this works or not and it didn't actually
   <<endl;
   cout<<m[0].code<<"\t"<<m[0].name;
   getch();
   return 0;
}

2 个答案:

答案 0 :(得分:6)

简洁 - 您不能在C ++中使用struct menu编写,只需使用默认构造函数。

在C99中,你可以使用:

m[0] = (struct menu){ 1, "MAGGI" };  // C99 compound literal

即使在C ++ 11中,(即“使用复合文字”)也无效。


endl;的简单使用尝试生成函数指针,但函数被重载,因此无法编译。但是,您应该在输出的末尾添加<< endl


G ++允许C99风格的复合文字

有趣的是,GCC(在Mac OS X 10.8.4上测试GCC 4.7.1)接受复合文字符号,即使有严格的警告,但这是标准C ++的GCC / G ++扩展:

g++ -O3 -g -Wall -Wextra -c x91.cpp

代码:

#include <iostream>
using namespace std;

struct menu
{
    int code;
    char name[30];
} m[5];

int main()
{
   m[0] = (struct menu){ 1, "MAGGI" };
   cout << m[0].code << "\t" << m[0].name << endl;
   return 0;
}

你必须非常难以引起G ++的抱怨:

$ g++ -O3 -g -Wall -Wextra -std=c++98 -pedantic x91.cpp -o x91  
x91.cpp: In function ‘int main()’:
x91.cpp:11:34: warning: ISO C++ forbids compound-literals [-pedantic]
$ g++ -O3 -g -Wall -Wextra -std=c++11 -pedantic x91.cpp -o x91  
x91.cpp: In function ‘int main()’:
x91.cpp:11:34: warning: ISO C++ forbids compound-literals [-pedantic]
$

C ++ 2011和'list initialization'或'extended initializer lists'

我认为第8.5节初始化程序和8.5.4列表初始化特别意味着如果你的类(示例中的结构)具有适当的支持,你实际上可以写出你原来拥有的东西。

考虑原始代码的这个小变体:

#include <iostream>
#include <cstring>
using namespace std;

struct menu
{
    int  code;
    char name[30];
    menu(int c, const char *n) : code(c) { strncpy(name, n, sizeof(name)); name[sizeof(name)-1] = '\0'; }
    menu() : code(0) { name[0] = '\0'; }
} m[5];

int main()
{
   menu m0 = { 2, "MAGGI 2" };
   m[0] = (struct menu){ 1, "MAGGI 1" };
   m[1] = { 3, "MAGGI 3" };
   cout << m[0].code << "\t" << m[0].name << endl;
   cout << m0.code << "\t" << m0.name << endl;
   cout << m[1].code << "\t" << m[1].name << endl;
   return 0;
}

此代码在G ++下编译正常,但如果编译如下所示,可能会出现关于复合文字不属于标准C ++的警告:

$ g++ -O3 -g -Wall -Wextra -std=c++11 -pedantic x91.cpp -o x91  
x91.cpp: In function ‘int main()’:
x91.cpp:16:39: warning: ISO C++ forbids compound-literals [-pedantic]
$ ./x91
1   MAGGI 1
2   MAGGI 2
3   MAGGI 3
$

我们可以辩论使用strncpy()的智慧 - 这与正在讨论的主题相关。需要默认构造函数来允许定义数组。扩展列表初始化需要另一个构造函数。注释掉非默认构造函数,你会收到大量的编译消息:

$ g++ -O3 -g -Wall -Wextra -std=c++11 -pedantic x91.cpp -o x91
x91.cpp: In function ‘int main()’:
x91.cpp:15:29: error: could not convert ‘{2, "MAGGI 2"}’ from ‘<brace-enclosed initializer list>’ to ‘menu’
x91.cpp:16:39: warning: ISO C++ forbids compound-literals [-pedantic]
x91.cpp:16:39: error: no matching function for call to ‘menu::menu(<brace-enclosed initializer list>)’
x91.cpp:16:39: note: candidates are:
x91.cpp:10:5: note: menu::menu()
x91.cpp:10:5: note:   candidate expects 0 arguments, 2 provided
x91.cpp:5:8: note: constexpr menu::menu(const menu&)
x91.cpp:5:8: note:   candidate expects 1 argument, 2 provided
x91.cpp:5:8: note: constexpr menu::menu(menu&&)
x91.cpp:5:8: note:   candidate expects 1 argument, 2 provided
x91.cpp:17:26: error: no match for ‘operator=’ in ‘m[1] = {3, "MAGGI 3"}’
x91.cpp:17:26: note: candidates are:
x91.cpp:5:8: note: menu& menu::operator=(const menu&)
x91.cpp:5:8: note:   no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘const menu&’
x91.cpp:5:8: note: menu& menu::operator=(menu&&)
x91.cpp:5:8: note:   no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘menu&&’
$

在C ++ 98模式下(两个构造函数都存在),您会收到有关在C ++ 11兼容模式之外使用“扩展初始化列表”的警告:

$ g++ -O3 -g   -Wall -Wextra -std=c++98 -pedantic x91.cpp -o x91  
x91.cpp: In function ‘int main()’:
x91.cpp:15:29: error: in C++98 ‘m0’ must be initialized by constructor, not by ‘{...}’
x91.cpp:16:39: warning: ISO C++ forbids compound-literals [-pedantic]
x91.cpp:17:26: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
$

答案 1 :(得分:1)

声明struct的构造函数并使用它们。也尝试在char []上使用std :: string。你不可能像你一样做。构造函数可以是

menu(int _code, string _name):code(_code), name(_name)
{} //changing name to string

有了这个,不要忘记声明一个默认的构造函数以及你正在创建一个struct变量数组