установить
npm install --save babel-plugin-transform-object-rest-spread
npm install --save babel-preset-env
.babelrc
{
"presets":[
"env","es2015", "react"
],
"plugins": [
"react-hot-loader/babel", "transform-object-rest-spread"
]
}
package.json
[112 ]Простое решение состоит в том, чтобы изменить объявление str
кому:
char str[] = "abc";
Это делает str
массив символа, который инициализируется к строке "abc". В настоящее время Вы имеете str
как указатель на символ, инициализированный для указания на строку, описанную строковым литералом. Существует основное отличие: строковые литералы только для чтения для предоставления гибкости максимума компилятора на том, где сохранить их; это - UB для изменения их. Но массивы символа изменяемы, и таким образом, он должен хорошо изменить их.
PS. main()
возвраты int
.
Так как Вы учитесь для экзамена, я изложу в деталях свои комментарии немного для объяснения, что на самом деле происходит:
char *str = "abc";
str
указатель, сохраненный на стеке. Это инициализируется для указания на литеральную строку "abc"
. Та литеральная строка будет сохраненной в разделе данных Вашего скомпилированного исполняемого файла и загружается в память, когда Ваша программа загружается. Тот раздел памяти только для чтения, поэтому когда Вы пытаетесь изменить данные, на которые указывает ул., Вы получаете нарушение прав доступа.
char* str = malloc(sizeof(char) * 4);
strcpy(str, "abc");
Здесь, ул. является тем же указателем вершины стека как первый пример. На этот раз это инициализируется, чтобы указать на блок с 4 символами памяти на "куче", что можно и читать и записать. Сначала тот блок памяти является неинициализированным и может содержать что-либо. strcpy читает блок постоянной памяти, где "abc" хранится и копирует его в блок памяти чтения-записи, та ул. указывает на. Отметьте ту установку str[3] = '\0'
избыточно, так как strcpy уже делает это.
Как в стороне, если Вы работаете в Visual Studio, strcpy_s использования вместо этого, чтобы удостовериться, что Вы не перезаписываете свой буфер, если скопированная строка длиннее, чем Вы ожидали.
char str[] = "abc";
Здесь str
теперь массив, выделенный на стеке. Компилятор будет, измерил его, точно соответствуют, строковый литерал раньше инициализировал его (включая ПУСТОЙ разделитель). Стековая память является чтением-записью, таким образом, можно изменить значения в массиве однако, Вы хотите.
char str[4] = "abc";
Это - эффективно то же как предыдущая версия, только Вы говорите компилятору, что знаете лучше, чем это делает, какой длины массив должен быть. Можно попасть в беду, если Вы меняете струну а не размер массива.
Поскольку это - домашняя работа, я дам совет, но я не отправлю полное решение.
Я предполагаю, что Вы получаете нарушение прав доступа на ул. [0] = 'b'? Это вызвано тем, что "abc" является строковым литералом.
Скопируйте строковые точки ул. в перед называнием реверса или станьте обратными, чтобы выделить буфер и поместить обратную строку в это.
Следует иметь в виду, что необходимо будет освободить всю память, которую Вы выделяете.
Lordy, Lordy. Ко всему те, которые предлагают способы на самом деле выполнить обмен, считайте вопрос тщательно; нет ничего худшего, чем необходимость повторить уже совершенно членораздельный вопрос. Независимо от метода, используемого для реализации обмена (временная подкачка, xor3-подкачка, и т.д.), этот человек, кажется, слишком знаком с фундаментальным и довольно элементарным intrinsics функции.
Однако, как уже объяснено, компилятор/компоновщик в общем помещает все строковые литералы в 'сегменте данных константы' целевого исполняемого файла, который впоследствии связан с незаписываемым дескриптором MMU во время соответствующего вызова 'загрузки/должностного лица'. Все циклы записи ЦП, впоследствии выпущенные через этот дескриптор, автоматически захватываются механизмом исключения MMU, приводящим к обязательному 'segfault' или определенному для платформы эквиваленту. Это само собой разумеется, конечно, более старые non-MMU платформы не показали бы такого поведения.
Хотя это эффективно обеспечивает поддержку во время выполнения 'постоянной/литеральной' идиомы исходного языка, несколько платформ исторически упростили явные переопределения сегмента времени компиляции. Однако этот уровень поддержки медленно уменьшался в пользу более твердого/устойчивого уровня абстракции, таким образом представляя много очевидных и часто полезных ненадежных оптимизаций. Как время и истощение приводит к его постоянно старению философия "MC/ASM" перед слишком нетерпеливым поколением "Microsoft", программистов больше не считают хорошо осведомленными или достаточно ответственными для создания этого вида из решения. Вместо изобретенных многих, для не высказывания творческий реализации я засвидетельствовал как руководитель проекта, это ни в коем случае не плохая вещь.
Хотя это сообщение быстро развивается во вне темы нарушение, я чувствую себя несколько доказанным постоянным потоком нисходящих связанных вопросов, которые медленно становятся местными в нашей промышленности. Как неоперившийся программист C - язык, первоначально разработанный для дополнения разработки низкого уровня - мой совет состоит в том, чтобы принять подход снизу вверх и увеличить исследования с небольшой внеучебной разработкой ассемблера. Поскольку алгоритмическая реализация, вероятно, составит Ваше основное внимание как инженера приложений, важно помнить, что современный дизайн ЦП испытал гомогенную эволюцию за прошлые 30 лет; сегодняшний сверхбыстрый Intel CPUs является не больше, чем суперскалярными улучшениями CMOS 4/8-bit биполярных процессоров, которые я программировал, когда Земля была все еще молода.
Вопреки широко распространенному мнению программирование ассемблера относительно легко изучить, и абсолютно необходимый при попытке согласовать высокоуровневые конструкции с проблематичным или тайным поведением. После того как Вы учитываете в бесконечные часы экспериментирования, отладки, веб-поиска и спама форума, может быть несомненно, что подход снизу вверх является, конечно, путем наименьшего сопротивления.
Удача с Вашими исследованиями.
Насколько я знаю, постоянные строки реализованы как массивы постоянных символов (или, в терминах C, const char [length]
). Поэтому Вы не можете изменить его символы.
Попытка, динамично выделяющая строку.
char* str = (char*)malloc(sizeof(char) * 4);
strcpy(str, "abc");
str[3] = '\0';
Конечно, не забывайте освобождать память в конце своей программы.
Править: Я не отправлю ничего связанного с инвертированием строки, потому что это - Ваша работа.