Каков тип строковых литералов в C и C++?

Каков тип строкового литерала в C? Это char * или const char * или const char * const?

Что относительно C++?

60
задан Lundin 26 April 2016 в 07:10
поделиться

3 ответа

Согласитесь с остальными, если null является допустимым возвращаемым значением, верните его, но в противном случае нет.

Что я хотел бы добавить, так это то, что вы также можете различать отмеченные и не отмеченные исключения. В некоторых случаях может быть целесообразно использовать неконтролируемое исключение, например, пользователь вашего API, вероятно, не в ситуации, чтобы иметь дело с этим исключением в любом случае. Spring Framework очень часто использует неконтролируемые исключения, что делает код часто более простым для чтения, но его труднее отследить ошибки иногда.

-121--2321910-

Для передачи состояния ошибки всегда используется возвращаемое значение. Если вам нужно передать одно значение, я бы использовал выходной параметр.

образец хранимой процедуры, с параметром OUTPUT:

CREATE PROCEDURE YourStoredProcedure 
(
    @Param1    int
   ,@Param2    varchar(5)
   ,@Param3    datetime OUTPUT
)
AS
IF ISNULL(@Param1,0)>5
BEGIN
    SET @Param3=GETDATE()
END
ELSE
BEGIN
    SET @Param3='1/1/2010'
END
RETURN 0
GO

вызов хранимой процедуры, с параметром OUTPUT:

DECLARE @OutputParameter  datetime
       ,@ReturnValue      int

EXEC @ReturnValue=YourStoredProcedure 1,null, @OutputParameter OUTPUT
PRINT @ReturnValue
PRINT CONVERT(char(23),@OutputParameter ,121)

OUTPUT:

0
2010-01-01 00:00:00.000
-121--777307-

В C типом строкового литерала является char [] - это не const в соответствии с типом, но это неопределенное поведение для изменения Кроме того, 2 строковых литерала, которые имеют одинаковое содержимое (или достаточно одного содержимого), могут совместно использовать одни и те же элементы массива.

Из C99 стандартного 6,4,5/5 "Строковые литералы - Семантика":

В фазе трансляции 7 к каждой многобайтовой последовательности символов добавляется байт или код с нулевым значением, который является результатом строкового литерала или литералов. Многобайтовая символьная последовательность затем используется для инициализации массива статической длительности и длины хранения, достаточных для того, чтобы содержать последовательность. Для символьных строковых литералов элементы массива имеют тип char и инициализируются отдельными байтами многобайтовой символьной последовательности; для широких строковых литералов элементы массива имеют тип wchar _ t и инициализируются последовательностью широких символов...

Не указано, отличаются ли эти массивы при условии, что их элементы имеют соответствующие значения. Если программа пытается изменить такой массив, поведение не определено.

В C++ "обычный строковый литерал имеет массив типа 'n const char '" (из 2.13.4/1 "строковые литералы"). Но в стандарте C++ есть особый случай, когда указатель на строковые литералы легко преобразуется в неконсцентифицированные указатели (4.2/2 "Преобразование массива в указатель"):

Строковый литерал (2.13.4), не являющийся широким строковым литералом, может быть преобразован в значение типа "указатель на символ"; широкострочный литерал может быть преобразован в значение rvalue типа "указатель на" wchar_t.

В качестве побочного примечания - так как массивы в C/C + + так легко преобразуются в указатели, строковый литерал часто может использоваться в контексте указателя, так же как и любой массив в C/C + +.


Дополнительная редакция: то, что следует ниже, действительно является главным образом спекуляцией с моей стороны относительно обоснования выбора стандартов C и C++, сделанных в отношении строковых типов литералов. Поэтому возьмите его с зерном соли (но, пожалуйста, прокомментируйте, если у вас есть исправления или дополнительные детали):

Я думаю, что стандарт C предпочел сделать последовательность буквенные типы неконста, потому что было (и есть) столько кода, что ожидает возможность использовать неконст-квалифицированные указатели символов , которые точку к литералам. Когда был добавлен квалификатор const (что, если я не ошибаюсь, было сделано примерно во время стандартизации ANSI, но долго после того, как K & R C был вокруг, чтобы накопить тонну существующего кода) если бы они сделали указатели на строковые литералы только для назначения char const * типов без приведения почти каждой существующей программы требовало бы изменения. Не лучший способ получить принятый стандарт...

Я полагаю, что изменение на C++, что последовательности литералы const квалифицированы, было сделано в основном для поддержки того, чтобы позволить литерал последовательности более подходящим образом соответствовать перегрузке, которая принимает аргумент « char const * ». Я думаю, что также было желание закрыть воспринимаемую дыру в системе типов, но дыра была в значительной степени открыта обратно специальным случаем в преобразованиях массив-указатель.

Приложение D стандарта указывает, что "неявное преобразование из критерия const в критерий non-const для строковых литералов (4.2) устарел ", но я думаю, что столько кода все равно сломается, что пройдет много времени, прежде чем реализаторы компилятора или комитет по стандартам захотят фактически отключить (если только не может быть разработана какая-то другая умная техника - но тогда дыра вернется, не так ли?).

60
ответ дан 24 November 2019 в 17:53
поделиться

Строковый литерал AC имеет тип char [n] где n равно количеству символов + 1 для учета неявного нуля в конце строки.

Массив будет размещен статически; это не const , но его изменение - неопределенное поведение.

Если он имел тип указателя char * или неполный тип char [] , sizeof не мог работать должным образом.

Создание строковых литералов const - это идиома C ++, а не часть какого-либо стандарта C.

10
ответ дан 24 November 2019 в 17:53
поделиться

Раньше они были типа char [] . Теперь они имеют тип const char [] .

0
ответ дан 24 November 2019 в 17:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: