Урок №22. директивы препроцессора

Директива #define

Директива #define позволяет вводить в текст программы константы и макроопределения.
Общая форма записи

#define Идентификатор Замена

ИдентификаторЗамена#defineЗаменаИдентификатор

12345678

#include <stdio.h>#define A 3int main(){  printf(«%d + %d = %d», A, A, A+A); // 3 + 3 = 6  getchar();  return 0;}

  • U или u представляет целую константу в беззнаковой форме (unsigned);
  • F (или f) позволяет описать вещественную константу типа float;
  • L (или l) позволяет выделить целой константе 8 байт (long int);
  • L (или l) позволяет описать вещественную константу типа long double

#define A 280U   // unsigned int#define B 280LU  // unsigned long int#define C 280    // int (long int)#define D 280L   // long int#define K 28.0   // double#define L 28.0F  // float#define M 28.0L  // long double

 
идентификатор(аргумент1, …, агрументn)

заменаПример на Си

12345678910111213141516

#include <stdio.h>#include <stdlib.h>#include <math.h>#define PI 3.14159265#define SIN(x) sin(PI*x/180)int main(){  int c;  system(«chcp 1251»);  system(«cls»);  printf(«Введите угол в градусах: «);  scanf(«%d», &c);  printf(«sin(%d)=%lf», c, SIN(c));  getchar(); getchar();  return 0;}

Результат выполнения

Отличием таких макроопределений от функций в языке Си является то, что на этапе компиляции каждое вхождение идентификатора замещается соответствующим кодом. Таким образом, программа может иметь несколько копий одного и того же кода, соответствующего идентификатору

В случае работы с функциями программа будет содержать 1 экземпляр кода, реализующий указанную функцию, и каждый раз при обращении к функции ей будет передано управление.
Отменить макроопределение можно с помощью директивы #undef.
Однако при использовании таких макроопределений следует соблюдать осторожность, например

12345678910111213

#include <stdio.h>#define sum(A,B) A+Bint main(){  int a, b, c, d;  a = 3; b = 5;  c = (a + b) * 2; // c = (a + b)*2  d = sum(a, b) * 2; // d = a + b*2;  printf(» a = %d\n b = %d\n», a, b);  printf(» c = %d \n d = %d \n», c, d);  getchar();  return 0;}

\

1234567891011121314

#include <stdio.h>#define sum(A,B) A + \                 Bint main(){  int a, b, c, d;  a = 3; b = 5;  c = (a + b) * 2; // c = (a + b)*2  d = sum(a, b) * 2; // d = a + b*2;  printf(» a = %d\n b = %d\n», a, b);  printf(» c = %d \n d = %d \n», c, d);  getchar();  return 0;}

#define##

123456789

#include <stdio.h>#define SUM(x,y) (a##x + a##y)int main(){  int a1 = 5, a2 = 3;  printf(«%d», SUM(1, 2)); // (a1 + a2)  getchar();  return 0;}

Реализация#

Мне понадобилось пара дней на то, чтобы пройти от генерации идеи до её реализации. Я ни разу не дизайнер, так что заимствовавал идеи уже давно существующих веб-сайтов. В итоге получился простой и ёмкий, в плане отображения информации, интерфейс.

В ходе скрейпинга увидел дополнительную информацию с сайтов Сan I Use и MDN по каждому тегу, расположенную на странице спецификации HTML в виде небольших бейджиков. В итоге решил разместить информацию о поддержке тегов разными браузерами сразу под сравниваемыми тегами. Чтобы, как говорится, всё было под рукой, в развёрнутом виде.

Так как не использовал JS на клиенте, то в мобильном представлении сделал переключение табов со сравниваемыми тегами с помощью CSS-селекторов.

Images

SlideshowSlideshow GalleryModal ImagesLightboxResponsive Image GridImage GridTab GalleryImage Overlay FadeImage Overlay SlideImage Overlay ZoomImage Overlay TitleImage Overlay IconImage EffectsBlack and White ImageImage TextImage Text BlocksTransparent Image TextFull Page ImageForm on ImageHero ImageBlur Background ImageChange Bg on ScrollSide-by-Side ImagesRounded ImagesAvatar ImagesResponsive ImagesCenter ImagesThumbnailsBorder Around ImageMeet the TeamSticky ImageFlip an ImageShake an ImagePortfolio GalleryPortfolio with FilteringImage ZoomImage Magnifier GlassImage Comparison Slider

Header guards

На самом деле решение простое — использовать header guards (защиту подключения в C++). Header guards — это директивы , которые состоят из следующего:

#ifndef SOME_UNIQUE_NAME_HERE
#define SOME_UNIQUE_NAME_HERE

// Основная часть кода

#endif

1
2
3
4
5
6

#ifndef SOME_UNIQUE_NAME_HERE
#define SOME_UNIQUE_NAME_HERE

// Основная часть кода

#endif

Если подключить этот заголовочный файл, то первое, что он сделает — это проверит, был ли ранее определен идентификатор . Если мы впервые подключаем этот заголовок, то ещё не был определен. Следовательно, мы определяем (с помощью директивы #define) и выполняется основная часть заголовочного файла. Если же мы раньше подключали этот заголовочный файл, то уже был определен. В таком случае, при подключении этого заголовочного файла во второй раз, его содержимое будет проигнорировано.

Все ваши заголовочные файлы должны иметь header guards. может быть любым идентификатором, но, как правило, в качестве идентификатора используется имя заголовочного файла с окончанием . Например, в файле math.h идентификатор будет :

math.h:

#ifndef MATH_H
#define MATH_H

int getSquareSides()
{
return 4;
}

#endif

1
2
3
4
5
6
7
8
9

#ifndef MATH_H
#define MATH_H

intgetSquareSides()

{

return4;

}

#endif

Даже заголовочные файлы из Стандартной библиотеки С++ используют header guards. Если бы вы взглянули на содержимое заголовочного файла iostream, то вы бы увидели:

#ifndef _IOSTREAM_
#define _IOSTREAM_

// основная часть кода

#endif

1
2
3
4
5
6

#ifndef _IOSTREAM_
#define _IOSTREAM_

// основная часть кода

#endif

Но сейчас вернемся к нашему примеру с math.h, где мы попытаемся исправить ситуацию с помощью header guards:

math.h:

#ifndef MATH_H
#define MATH_H

int getSquareSides()
{
return 4;
}

#endif

1
2
3
4
5
6
7
8
9

#ifndef MATH_H
#define MATH_H

intgetSquareSides()

{

return4;

}

#endif

geometry.h:

#include «math.h»

1 #include «math.h»

main.cpp:

#include «math.h»
#include «geometry.h»

int main()
{
return 0;
}

1
2
3
4
5
6
7

#include «math.h»
#include «geometry.h»

intmain()

{

return;

}

Теперь, при подключении в main.cpp заголовочного файла math.h, препроцессор увидит, что не был определен, следовательно, выполнится директива определения и содержимое math.h скопируется в main.cpp. Затем main.cpp подключает заголовочный файл geometry.h, который, в свою очередь, подключает math.h. Препроцессор видит, что уже был ранее определен и содержимое geometry.h не будет скопировано в main.cpp.

Вот так можно бороться с дублированием определений с помощью header guards.

-Wextra

«Агрегатор» дополнительных предупреждений. Включает много интересного, чего нет в (как и в случае с , рассмотрены будут не все возможности).

Предупреждает о пустом теле условных выражений или цикла . Чаще всего это говорит об опечатке, меняющей логику программы:

См. также .

Предупреждает о «проваливании» в операторе :

Компилятор предполагает, что программист забыл , и не должен проваливаться:

В C++17 для обозначения явного намерения появился специальный атрибут — :

Предупреждает о том, что отдельные члены структуры не были проинициализированы. Скорее всего это просто забыли сделать:

Предупреждает о ненужном вызове в случаях, когда компилятор сам сделает всё, что нужно:

Предупреждает о сравнениях, которые всегда имеют один и тот же результат. Например, когда беззнаковое число проверяется на неотрицательность. Если программист делает такую проверку, то, видимо, предполагает, что число в теории может быть отрицательным, однако, это не так. Видимо, он где-то ошибся:

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

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

В C++17 для явного выражения намерения существует атрибут :

Предупреждает о том, что в параметр функции было записано значение, но после этого он ни разу не использовался. Возможно, про него снова забыли:

Почему iostream пишется без окончания .h?

Ещё один часто задаваемый вопрос: «Почему iostream (или любой другой из стандартных заголовочных файлов) при подключении пишется без окончания «.h»?». Дело в том, что есть 2 отдельных файла: iostream.h (заголовочный файл) и просто iostream! Для объяснения потребуется краткий экскурс в историю.

Когда C++ только создавался, все файлы библиотеки Runtime имели окончание .h. Оригинальные версии cout и cin объявлены в iostream.h. При стандартизации языка С++ комитетом ANSI, решили перенести все функции из библиотеки Runtime в пространствo имен std, дабы предотвратить возможность возникновения конфликтов имен с пользовательскими идентификаторами (что, между прочим, является хорошей идеей). Тем не менее, возникла проблема: если все функции переместить в пространство имен std, то старые программы переставали работать!

Для обеспечения обратной совместимости ввели новый набор заголовочных файлов с теми же именами, но без окончания «.h». Весь их функционал находится в пространстве имен std. Таким образом, старые программы с не нужно было переписывать, а новые программы уже могли использовать .

Когда вы подключаете заголовочный файл из Стандартной библиотеки C++, убедитесь, что вы используете версию без .h (если она существует). В противном случае вы будете использовать устаревшую версию заголовочного файла, который уже больше не поддерживается.

Кроме того, многие библиотеки, унаследованные от языка Cи, которые до сих пор используются в C++, также были продублированы с добавлением префикса (например, stdlib.h стал cstdlib). Функционал этих библиотек также перенесли в пространство имен std, дабы избежать возможность возникновения конфликтов имен с пользовательскими идентификаторами.

Правило: При подключении заголовочных файлов из Стандартной библиотеки С++, используйте версию без «.h» (если она существует). Пользовательские заголовочные файлы должны иметь окончание «.h».

Интерфейс#

При обращении по адресу caninclude.glitch.me открывается следующая страница:

Весёлый текстовый логотип и два поля встречают пользователя: в левом нужно ввести название тега, который вы вкладываете, в правом — тега, в который вы вкладываете. После этого, нужно нажать клавишу Enter или кликнуть по кнопке с вопросом.

В результате отправки формы по методу GET рендерится страница с информацией по двум тегам и вердиктом о вложенности.

Если определить возможность вкладывания не получилось из-за «прозрачной» контентной модели внешнего тега, то страница будет выглядеть так:

В случае, если вкладывать теги нельзя, то страница с вердиктом будет выглядеть так:

Можно ли записывать определения в заголовочных файлах?

C++ не будет жаловаться, если вы это сделаете, но так делать не принято.

Как уже было сказано выше, при подключении заголовочного файла, всё его содержимое вставляется сразу же после строчки с #include. Это означает, что любые определения, которые есть в заголовочном файле, скопируются в ваш файл.

Для небольших проектов, это, скорее всего, не будет проблемой. Но для более крупных это может способствовать увеличению времени компиляции (так как код будет повторно компилироваться) и размеру исполняемого файла. Если внести изменения в определения, которые находятся в файле .cpp, то перекомпилировать придется только этот файл. Если же внести изменения в определения, которые записаны в заголовочном файле, то перекомпилировать придется каждый файл, который подключает этот заголовок, используя директиву препроцессора #include. И вероятность того, что из-за одного небольшого изменения вам придется перекомпилировать весь проект, резко возрастает!

Иногда делаются исключения для простых функций, которые вряд ли изменятся (например, где определение состоит всего лишь из одной строки).

Основные директивы препроцессора

#include — вставляет текст из указанного файла#define — задаёт макроопределение (макрос) или символическую константу#undef — отменяет предыдущее определение#if — осуществляет условную компиляцию при истинности константного выражения#ifdef — осуществляет условную компиляцию при определённости символической константы#ifndef — осуществляет условную компиляцию при неопределённости символической константы#else — ветка условной компиляции при ложности выражения#elif — ветка условной компиляции, образуемая слиянием else и if#endif — конец ветки условной компиляции#line — препроцессор изменяет номер текущей строки и имя компилируемого файла#error — выдача диагностического сообщения#pragma — действие, зависящее от конкретной реализации компилятора.

Пишем свои собственные заголовочные файлы

Теперь давайте вернемся к примеру, который мы обсуждали в предыдущем уроке. У нас было два файла: add.cpp и main.cpp.

add.cpp:

int add(int x, int y)
{
return x + y;
}

1
2
3
4

intadd(intx,inty)

{

returnx+y;

}

main.cpp:

#include <iostream>

int add(int x, int y); // предварительное объявление с использованием прототипа функции

int main()
{
std::cout << «The sum of 3 and 4 is » << add(3, 4) << std::endl;
return 0;
}

1
2
3
4
5
6
7
8
9

#include <iostream>

intadd(intx,inty);// предварительное объявление с использованием прототипа функции

intmain()

{

std::cout<<«The sum of 3 and 4 is «<<add(3,4)<<std::endl;

return;

}

(если вы создаете все файлы заново, то не забудьте добавить add.cpp в свой проект, чтобы он был подключен к компиляции)

Мы использовали предварительное объявление, чтобы сообщить компилятору, что такое add(). Как мы уже говорили, записывать в каждом файле предварительные объявления используемых функций — дело не слишком увлекательное.

И здесь нам на помощь приходят заголовочные файлы. Достаточно просто написать один заголовочный файл и его можно будет повторно использовать в любом количестве программ. Также и вносить изменения в такой код (например, добавление ещё одного параметра) гораздо легче, нежели шерстить по всем файлам в поисках используемых функций.

Написать свой собственный заголовочный файл не так уж и сложно. Заголовочные файлы состоят из двух частей:

   Директивы препроцессора — в частности, header guards, которые предотвращают вызов заголовочного файла больше одного раза из одного и того же файла (об этом детально на следующем уроке).

   Содержимое заголовочного файла — набор объявлений.

Все ваши заголовочные файлы (которые вы написали самостоятельно) должны иметь расширение .

add.h:

// Начнем с директив препроцессора. ADD_H – это произвольное уникальное имя (обычно используется имя заголовочного файла)
#ifndef ADD_H
#define ADD_H

// А это уже содержимое заголовочного файла
int add(int x, int y); // прототип функции add() (не забывайте точку с запятой в конце!)

// Заканчиваем директивой препроцессора
#endif

1
2
3
4
5
6
7
8
9

// Начнем с директив препроцессора. ADD_H – это произвольное уникальное имя (обычно используется имя заголовочного файла)
#ifndef ADD_H
#define ADD_H
 
// А это уже содержимое заголовочного файла

intadd(intx,inty);// прототип функции add() (не забывайте точку с запятой в конце!)

 
// Заканчиваем директивой препроцессора
#endif

Чтобы использовать этот файл в main.cpp, вам сначала нужно будет подключить его к проекту.

main.cpp, в котором мы подключаем add.h:

#include <iostream>
#include «add.h»

int main()
{
std::cout << «The sum of 3 and 4 is » << add(3, 4) << std::endl;
return 0;
}

1
2
3
4
5
6
7
8

#include <iostream>
#include «add.h»

intmain()

{

std::cout<<«The sum of 3 and 4 is «<<add(3,4)<<std::endl;

return;

}

add.cpp остается без изменений:

int add(int x, int y)
{
return x + y;
}

1
2
3
4

intadd(intx,inty)

{

returnx+y;

}

Когда компилятор встречает , он копирует всё содержимое add.h в текущий файл. Таким образом, мы получаем предварительное объявление функции add().

Примечание: При подключении заголовочного файла, всё его содержимое вставляется сразу же после строчки .

Если вы получили ошибку от компилятора, что add.h не найден, то убедитесь, что имя вашего файла точно «add.h». Вполне возможно, что вы могли сделать опечатку, например, просто «add» (без «.h») или «add.h.txt» или «add.hpp».

Если вы получили ошибку от линкера, что функция аdd() не определена, то убедитесь, что вы корректно подключили add.cpp к вашему проекту (и к компиляции тоже)!

Purpose

The directive allows libraries of code to be developed which help to:

  • ensure that everyone uses the same version of a data layout definition or procedural code throughout a program,
  • easily cross-reference where components are used in a system,
  • easily change programs when needed (only one master file must be edited, versus modifying each instance an identical datatype is used, or function is called), and
  • save time by not needing to code extensive data layouts (minor, but useful).

An example situation which benefits from the use of an include directive is when referring to functions in a different file. Suppose we have a function in one file, which is then declared (with a function prototype) and then referred to in a second source file as follows:

int add(int, int);

int triple(int x)
{
    return add(x, add(x, x));
}

One drawback of this method is that the prototype must be present in all files that use the function. Another drawback is that if the return type or arguments of the function are changed, these prototypes will have to be updated. Putting the prototype in a single, separate file avoids these problems. Assuming the prototype is moved to the file , the second source file can then become:

#include "add.h"

int triple(int x)
{
    return add(x, add(x,x));
}

Now, every time the code is compiled, the latest function prototypes in will be included in the files using them, avoiding potentially disastrous errors.

Add the JavaScript

HTML includes are done by JavaScript.

<script>function includeHTML() {  var z, i, elmnt, file, xhttp; 
/* Loop through a collection of all HTML elements: */  z =
document.getElementsByTagName(«*»);  for (i = 0; i < z.length; i++)
{    elmnt = z;    /*search for
elements with a certain atrribute:*/    file =
elmnt.getAttribute(«w3-include-html»);    if (file) {     
/* Make an HTTP request using the attribute value as the file name: */     
xhttp = new XMLHttpRequest();     
xhttp.onreadystatechange = function() {       
if (this.readyState == 4) {         
if (this.status == 200) {elmnt.innerHTML = this.responseText;}         
if (this.status == 404) {elmnt.innerHTML = «Page not found.»;}         
/* Remove the attribute, and call this function once more: */         
elmnt.removeAttribute(«w3-include-html»);         
includeHTML();        }     
}       xhttp.open(«GET», file, true);     
xhttp.send();      /* Exit the function: */     
return;    }  }}</script>

Call includeHTML() at the bottom of the page:

Нужно больше предупреждений

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

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

Аналогично, сообщает, что у класса есть закрытые функции-члены, а открытых нет ни одной.

Предупреждает о том, что у класса есть виртуальные функции-члены, но деструктор при этом не виртуальный. Очень сложно представить себе такой класс. Вероятнее всего, это ошибка.

Предупреждает о приведении типов в стиле языка C. В плюсах есть прекрасные и ужасные , , и , которые более локальны и более описательны. Сишный способ слишком сильный и — о, ужас, — небезопасный. Лучше его не использовать вообще.

Предупреждает о попытке в классе-наследнике перегрузить виртуальную функцию базового класса:

Крайне полезный флаг. Предупреждает о неочевидном выборе перегруженной функции:

Вероятнее всего, хотели-таки позвать вторую перегрузку, а не первую. А если всё-таки первую, то будьте любезны сказать об этом явно.

Предупреждает о том, что ветви и одинаковы:

Условный оператор также под прицелом:

Для меня абсолютная загадка, почему этот флаг не включён не то, что в , а вообще по умолчанию.

См. также .

Предупреждает об одинаковых условиях в цепочках :

См. также .

Предупреждает о проверке на равенство между двумя числами с плавающей точкой. Скорее всего, это ошибка, и сравнение нужно проводить с заданной точностью.

Полезная опция, которая не даёт перекрыть локальную переменную другой локальной переменной при условии, что они имеют совместимые типы.

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

Очень, очень, очень важный флаг. Он предупреждает об огромном количестве неявных сужающих (то есть потенциально приводящих к потере информации) преобразований, которые могут быть следствием ошибки программиста. Например:

Если вы раньше никогда не включали этот флаг, то будет интересно.

Предупреждает об использовании целочисленного нуля вместо .

Флаг для педантов. Сообщает о лишней точке с запятой после определения функции-члена.

Как и помогает предотвратить большое количество неявных преобразований, которые запросто могут быть ошибками:

Предупреждает о подозрительных логических выражениях. Например, когда вместо побитового «И» поставили логическое «И», или логическое выражение имеет одинаковые операнды:

Принцип работы#

Так как основная цель — удобно показать информацию о двух сравниваемых тегах, то для старта я решил реализовать простой способ проверки. Информация, представленная в спецификации, больше приспособлена для понимания человеком, чем машиной — хотя и человеку нужно приложить усилия, чтобы сопоставить несколько условий и решить, можно ли вкладывать теги.

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

У вкладываемого тега нужно проверить секцию Categories, а у родительского тега — Content model.

В простом случае, наличие одного из пуктов из секции Categories в секции Сontent model, даёт положительный результат.
В случае с контентной моделью Transparent в секции Content model родительского тега, нужно обратить внимание на Content model родителя нашего родительского тега. То есть в таком случае вам нужно самостоятельно проверить следующий родительский тег из вашей разметки.
Есть и более сложный случай, где есть несколько «но»

Порой некторые атрибуты меняют возможность вкладывания.

Теперь про простой алгоритм проверки вложенности тегов:

  1. Во время скрейпинга в секциях каждого тега создаётся множество ключевых слов, в которое входят названия контентной модели, имена атрибутов и тегов.
  2. Если в секции есть Nothing, то в множество ключевых тегов включается название тега.
  3. Если есть модель Transparent в секции Content model родительского тега, то ситуация с включением тега не определена. В этом случае выдаётся сообщение, что нужно взять из разметки следующий внешний тег и повторить запрос. При этом следующий пункт не выполняется.
  4. Далее производится проверка на пересечение множеств:
    • если найдены общие ключевые слова — положительный вердикт, теги можно вкладывать.
    • если нет пересекающихся ключевых слов — отрицательный вердикт, теги нельзя вкладывать.

Использование свойств проекта в MSBuild и Visual StudioUsing project properties in MSBuild and Visual Studio

Хотя в директиве include можно использовать макросы Visual Studio, такие как $ (SolutionDir), они не работают в MSBuild.Although you can use Visual Studio macros like $(SolutionDir) in an include directive, they don’t work in MSBuild. Если требуется преобразовывать шаблоны на компьютере сборки, необходимо использовать свойства проекта.If you want to transform templates in your build machine, you have to use project properties instead.

Измените CSPROJ- или VBPROJ-файл для определения свойства проекта.Edit your .csproj or .vbproj file to define a project property. В этом примере определяется свойство с именем .This example defines a property named :

Теперь можно использовать свойство проекта в текстовых шаблонах, которые будут правильно преобразовываться как в Visual Studio, так и в MSBuild:Now you can use your project property in text templates, which transform correctly in both Visual Studio and MSBuild:

More

Fullscreen VideoModal BoxesDelete ModalTimelineScroll IndicatorProgress BarsSkill BarRange SlidersTooltipsDisplay Element HoverPopupsCollapsibleCalendarHTML IncludesTo Do ListLoadersStar RatingUser RatingOverlay EffectContact ChipsCardsFlip CardProfile CardProduct CardAlertsCalloutNotesLabelsCirclesStyle HRCouponList GroupList Without BulletsResponsive TextCutout TextGlowing TextFixed FooterSticky ElementEqual HeightClearfixResponsive FloatsSnackbarFullscreen WindowScroll DrawingSmooth ScrollGradient Bg ScrollSticky HeaderShrink Header on ScrollPricing TableParallaxAspect RatioResponsive IframesToggle Like/DislikeToggle Hide/ShowToggle Dark ModeToggle TextToggle ClassAdd ClassRemove ClassActive ClassTree ViewRemove PropertyOffline DetectionFind Hidden ElementRedirect WebpageZoom HoverFlip BoxCenter VerticallyCenter Button in DIVTransition on HoverArrowsShapesDownload LinkFull Height ElementBrowser WindowCustom ScrollbarHide ScrollbarDevice LookContenteditable BorderPlaceholder ColorText Selection ColorBullet ColorVertical LineDividersAnimate IconsCountdown TimerTypewriterComing Soon PageChat MessagesPopup Chat WindowSplit ScreenTestimonialsSection CounterQuotes SlideshowClosable List ItemsTypical Device BreakpointsDraggable HTML ElementJS Media QueriesSyntax HighlighterJS AnimationsGet Iframe Elements

Menus

Icon BarMenu IconAccordionTabsVertical TabsTab HeadersFull Page TabsHover TabsTop NavigationResponsive TopnavNavbar with IconsSearch MenuSearch BarFixed SidebarSide NavigationResponsive SidebarFullscreen NavigationOff-Canvas MenuHover Sidenav ButtonsSidebar with IconsHorizontal Scroll MenuVertical MenuBottom NavigationResponsive Bottom NavBottom Border Nav LinksRight Aligned Menu LinksCentered Menu LinkEqual Width Menu LinksFixed MenuSlide Down Bar on ScrollHide Navbar on ScrollShrink Navbar on ScrollSticky NavbarNavbar on ImageHover DropdownsClick DropdownsDropdown in TopnavDropdown in SidenavResp Navbar DropdownSubnavigation MenuDropupMega MenuMobile MenuCurtain MenuCollapsed SidebarCollapsed SidepanelPaginationBreadcrumbsButton GroupVertical Button GroupSticky Social BarPill NavigationResponsive Header

PHP include vs. require

The statement is also used to include a file into the PHP code.

However, there is one big difference between include and require; when a
file is included with the statement and PHP cannot find it, the script
will continue to execute:

Example

<html>
<body>
<h1>Welcome to my home page!</h1>
<?php include ‘noFileExists.php’;
echo «I have a $color $car.»;?>
</body>
</html>

If we do the same example using the statement, the
echo statement will not be executed because the script execution dies after the
statement returned a fatal error:

Example

<html>
<body>
<h1>Welcome to my home page!</h1>
<?php require ‘noFileExists.php’;
echo «I have a $color $car.»;?>
</body>
</html>

Use when the file is required by the application.

Use when the file is not required and application should continue when file is not found.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector