Да, у каждого приложения свой формат даты.
И даже каждое приложение может иметь более одного сеанса, каждый с различным форматом сеанса, указанным для DATE и TIMESTAMP.
SQL Developer имеет настройки уровня приложения, определенные на странице «Предпочтения», «База данных», «NLS». Вот как будут отображаться DATE, если вы не введете ALTER SESSION SET ... в своем рабочем листе SQL.
Или, если вы всегда хотите определенный формат независимо от этого параметра, встроите его в свой запрос.
select to_char(sysdate, 'DAY') today from dual;
Выбранный ответ Адама Розенфилда неверен. Ответ coobird тоже. По этой причине я проголосовал за оба ответа.
Интерпретация Адама Марковица * lineptr ++
верна, но он не отвечает на главный вопрос, является ли это допустимым кодом C99. Только Tom Future делает; к сожалению, он не объясняет * lineptr ++
. Я присвоил им по очку.
Итак, для краткости, lineptr
- это переменная, которой можно управлять как указателем. Таким образом, увеличение указателя является допустимым.
lineptr
- указатель на последовательность указателей на последовательности символов. Другими словами, это указатель на первую строку массива строк. Согласно коду мы можем предположить, что строки являются последовательностями символов с завершающим нулем ('\ 0'). nlines
- количество строк в массиве.
Выражение теста while: nlines-> 0
. nlines -
- пост-декремент (поскольку -
находится справа от переменной). Таким образом, он выполняется после теста и независимо от результата теста, так что в любом случае.
Итак, если значение nlines
, указанное в качестве аргумента, было 0
, тест выполняется первым и возвращает false
; инструкции в цикле не выполняются. Обратите внимание, поскольку nlines
все равно уменьшается, значение nlines
после цикла while
будет -1
.
If nlines == 1
, тест вернет true
и nlines
будут уменьшены; инструкции в цикле будут выполнены один раз. Обратите внимание, что пока эти инструкции выполняются, значение nlines
равно 0
. Когда тест выполняется снова, мы возвращаемся к случаю, когда nlines == 0
.
В инструкции printf
используется выражение * lineptr ++
. Это пост-инкремент указателя ( ++
справа от переменной). Это означает, что выражение вычисляется первым, а приращение выполняется после его использования. Таким образом, при первом выполнении printf
получает копию первого элемента массива строк, который является указателем на первый символ строки. lineptr
увеличивается только после этого. В следующий раз, когда printf
должен быть выполнен, lineptr
указывает на второй элемент и будет перемещен к третьему, когда вторая строка будет напечатана. Это имеет смысл, потому что мы, очевидно, хотим напечатать первую строку. Если бы Адам Розенфилд был прав, первая строка была бы пропущена, и в конце мы попытались бы вывести строку после последней, что, очевидно, плохо.
Таким образом, инструкция printf
является краткой формой двух следующих инструкций
printf("%s\n", *lineptr);
++lineptr; // or lineptr++, which is equivalent but not as good. lineptr += 1; is ok too.
. Обратите внимание, как практическое правило, когда пре- и пост-инкремент эквивалентны по своему действию, предварительный -increment предпочтительнее по соображениям производительности. Компиляторы позаботятся о том, чтобы переключить его за вас. Ну, большую часть времени. По возможности лучше обращаться к предоператорам самостоятельно, чтобы они использовались всегда.
lineptr
на самом деле не массив; это указатель на указатель. Обратите внимание, что оператор постинкремента ++
имеет более высокий приоритет, чем оператор разыменования *
, поэтому в lineptr ++
происходит следующее:
lineptr
получает увеличивается, чтобы указать на следующий элемент в массиве lineptr ++
является старое значение lineptr
, а именно указатель на текущий элемент в массиве * lineptr ++
разыменован, поэтому это значение текущего элемента в массиве Таким образом,
Продолжайте читать! В самом низу стр. 99
В качестве формальных параметров в определении функции
char s [];
и
char * s;
эквивалентны; мы предпочитаем последнее, потому что в нем более четко указано, что параметр является указателем.
Т.е. вы никогда не можете передать массив (который не является переменной) функции. Если вы объявляете функцию, которая выглядит так, как будто она принимает массив, она действительно принимает указатель (который является переменной). Это имеет смысл. Было бы странно, если бы аргумент функции не был переменной - он может иметь другое значение каждый раз, когда вы вызываете функцию, поэтому он точно не является константой!
Было бы проще представить * lineptr ++
следующим образом:
*(lineptr++)
Здесь указатель на массив char *
s равен перемещаемся к следующему элементу массива, то есть из lineptr [0]
, мы переходим к lineptr [1]
. (Приращение указателя происходит после разыменования из-за постфиксного приращения указателя.)
Таким образом, в основном происходит следующее:
lineptr [0]
(типа char *
) извлекается путем обращения. lineptr
.) lineptr [1]
, повторите процесс, начиная с шага 1.