c ++ Как я мог правильно предопределить массив char *? - PullRequest
1 голос
/ 14 декабря 2010

Я делаю это так:

int argc = 9;
char* argv[argc];

argv[0] = "c:/prog.exe";

но я получаю уведомление, что это устарело.Какой способ лучше?

Ответы [ 6 ]

1 голос
/ 14 декабря 2010

Помимо проблемы использования чего-то другого, кроме константного выражения для размера вашего массива ...

То, что устарело, - это тихое приведение строковых литералов к char*.Раньше все было в порядке:

char * hello = "hello";

Теперь оно должно быть:

char const* hello = "hello";

Это осуждение фактически содержится в Приложении в C ++ 03.

1 голос
/ 14 декабря 2010

Вы должны сделать это константой:

const char *argv[] = { "Arg1", "Arg2", "..." };

... или не использовать константы строковых литералов:

int argc = 9;
char* argv[argc];
char prog_name[] = "c:/prog.exe";
argv[0] = prog_name;
0 голосов
/ 14 декабря 2010

Кроме того, что все остальные указывали на константные строковые литералы, назначаемые неконстантным символьным указателям, и странность объявления argv и argc вне списка параметров main (), здесь есть дополнительная проблема с этой строкой:

char* argv[argc];

Вы можете использовать только целочисленные константные выражения для размеров массива в C ++;целочисленное константное выражение, являющееся буквальным целым числом в источнике вашей программы (например, "5" или "10"), значением перечисления (например, "red" из "enum colors {red, green, blue};"), sizeofexpression или переменная int, объявленная с помощью const:

// can hold 30 ints
int myarray1[30];

// can hold as many ints as myarray1 is wide in bytes
int myarray2[sizeof(myarray1)];

// C++ does not support variable-length arrays like C99 does, so if an int
// variable is used to specify array size, it must be marked const:
const int myarray3_size = 42;
int myarray3[myarray3];

Многие компиляторы C ++ реализуют массивы переменной длины в стиле C99, поэтому при их использовании вы можете не получить никаких жалоб, но их все же лучше избегать, еслиВы хотите написать переносимый код.

0 голосов
/ 14 декабря 2010

+ 1 для Влад.

Еще несколько объяснений от меня о том, что здесь происходит:

Вы получаете «устаревшее» предупреждение, потому что такой код:

"asdf"

теперь имеет тип const char*, а не char*. И строковые литералы могут быть преобразованы в char*, чтобы сохранить некоторую совместимость со старыми соглашениями, когда const не был таким строгим. Но преобразование строкового литерала в char* из const char* не рекомендуется, и на него не следует полагаться.

Почему? Строковый литерал - указатель на постоянную память, поэтому он должен быть const char*.

0 голосов
/ 14 декабря 2010

Давайте проанализируем, что вы здесь делаете:

// Create an int with value 9.
int argc = 9;

// Create an array of char* pointers of size 9
char* argv[argc];

// Assign the the first pointer to the global data string "C:\prog.exe"
argv[0] = "c:/prog.exe";

Я предполагаю, что вы не пытаетесь делать то, что я описал выше.Попробуйте что-то вроде этого:

// create an array of characters
char argv[] = "C:/prog.exe";

// argc in now the length of the string
int argc = sizeof argv;

-или -

// create an array of strings
char* argv[] = {"C:/prog.exe"};
// argc is now the number of strings in the array
int argc = 1;
0 голосов
/ 14 декабря 2010

Попробуйте использовать const, чтобы указать, что строки не будут изменены.

const char* argv[] = { "c:/prog.exe" };
const int argc = sizeof(argv) / sizeof(argv[0]);

int main()
{
    for(int i = 0; i < argc; ++i)
    {
        ::printf("%s\n", argv[i]);
    }
}

Здесь argc также будет рассчитываться автоматически во время компиляции, поэтому вероятность ошибки меньше (спасибоГозу за предложение).

...