Каков тип строкового литерала в C? Это char *
или const char *
или const char * const
?
Что относительно C++?
Согласитесь с остальными, если 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) устарел ", но я думаю, что столько кода все равно сломается, что пройдет много времени, прежде чем реализаторы компилятора или комитет по стандартам захотят фактически отключить (если только не может быть разработана какая-то другая умная техника - но тогда дыра вернется, не так ли?).
Строковый литерал AC имеет тип char [n]
где n
равно количеству символов + 1 для учета неявного нуля в конце строки.
Массив будет размещен статически; это не const
, но его изменение - неопределенное поведение.
Если он имел тип указателя char *
или неполный тип char []
, sizeof
не мог работать должным образом.
Создание строковых литералов const
- это идиома C ++, а не часть какого-либо стандарта C.
Раньше они были типа char []
. Теперь они имеют тип const char []
.