Иногда язык программирования ведёт себя не так, как этого ожидает программист. Сайт tproger.ru опубликовал перевод подборки забавных фич разных языков.
C/C++
1. В языке C можно индексировать массивы следующим образом:
[code]a[10][/code]
И это очень распространённый способ.
Однако существует и другая, менее известная реализация:
[code]10[a][/code]
Код означает то же самое, что и пример выше.
Примечание переводчика: Такой эффект возникает из-за того, что в языке C операция обращения по индексу a[b]
— это синтаксический сахар для *(a + b)
, что, конечно, эквивалентно *(b + a)
и в свою очередь b[a]
.
2. Триграф в C и C++:
[code]int main() {
printf("LOL??!");
}[/code]
На экран будет выведено LOL|
без ??!
, так как эти три знака формируют триграф |
.
Примечание переводчика: Триграфы были удалены в C++17.
3. В языке C метки case
оператора switch
могут находиться внутри вложенных блоков кода. Ниже приведён пример функции memcpy
с использованием этого метода.
[code]void duff_memcpy( char* to, char* from, size_t count ) {
size_t n = (count+7)/8;
switch( count%8 ) {
case 0: do{ *to++ = *from++;
case 7: *to++ = *from++;
case 6: *to++ = *from++;
case 5: *to++ = *from++;
case 4: *to++ = *from++;
case 3: *to++ = *from++;
case 2: *to++ = *from++;
case 1: *to++ = *from++;
}while(—n>0);
}
}[/code]
Примечание переводчика: Этот приём известен как «устройство Даффа».
4. Для каких странностей могут использоваться шаблоны в C++?
Лучше всего это продемонстрировано в «Многомерных аналоговых Литералах», которые используют шаблоны для вычисления площади нарисованных символами форм. Код ниже действителен для прямоугольника ниже.
[code]#include"analogliterals.hpp"
using namespace analog_literals::symbols;
unsigned int c = ( o——o
| !
! !
! !
o——o ).area;[/code]
Другой пример с кубом:
[code]assert( ( o————-o
|L \
| L \
| L \
| o————-o
| ! !
! ! !
o | !
L | !
L | !
L| !
o————-o ).volume == ( o————-o
| !
! !
! !
o————-o ).area * int(I————-I) );[/code]
Java
1. В Java следующий код:
[code]int[] numbers() {
return null;
}[/code]
Может быть записан таким образом:
[code]int numbers() [] {
return null;
}[/code]
2. Странное поведение при упаковке целых значений в Java:
[code]public class Scratch
{
public static void main(String[] args)
{
Integer a = 1000, b = 1000;
System.out.println(a == b);
Integer c = 100, d = 100;
System.out.println(c == d);
}
}[/code]
После запуска кода в первом случае будет выведено false
, а во втором — true
.
Примечание переводчика: Объяснение этой особенности языка хорошо описано на Stack Overflow.
PHP
1. Как PHP обрабатывает числовые значения в строках:
[code]"01a4" != "001a4"[/code]
Язык PHP не любит строки. Он ищет оправдания для того, чтобы рассматривать введённые в строки значения в виде чисел. Измените немного шестнадцатеричные символы, и PHP внезапно решит, что они уже не относятся к строкам — они становятся числами в научном понимании (PHP не важно, что вы использовали кавычки). Значения выше эквивалентны, так как нули перед другими цифрами игнорируются. Чтобы подкрепить это утверждение, давайте глянем на другой пример:
[code]"01e4" == "001e4"[/code]
Для PHP эти значения равны, и это задокументированное явление.
JavaScript
1. Странности при сложении и вычитании в JavaScript:
[code]’5′ + 3 // =’53′[/code]
Но при этом операция ниже выполняется согласно ожиданиям:
[code]’5′ — 3 // =2[/code]
2. Таблица «истины» в JavaScript:
[code]» == ‘0’ // false
0 == » // true
0 == ‘0’ // true
false == ‘false’ // false
false == ‘0’ // true
false == undefined // false
false == null // false
null == undefined // true
" \t\r\n" == 0 // true
[/code]
3. И ещё немного JS напоследок:
Примечание переводчика: Ещё у нас есть интересная статья о скрытых шутках и возможностях в Python.
А для вас что было самым странным и необычным в языках программирования, с которыми вы работаете?
[customscript]techrocks_custom_after_post_html[/customscript]
[customscript]techrocks_custom_script[/customscript]
Вы не написали самое элементарное про PHP, то как он сравнивает числа и строки и обратное!! Но про JS рассписали.