Реферат: С/C++
Отсутствие автоматической либо обязательной инициализации переменных. Плюс такого подхода - большая оптимальность кода, минус - необходимость производить инициализацию вручную. Отсутствие автоматической инициализации является потенциальной возможностью для разработки ПО, содержащего неустойчивые ошибки (в идеале компилятор должен отслеживать не производится ли чтение не инициализированной переменной и в случае, если проводится, обнулять ее).
Наличие множества "подводных камней"
scanf("%d %d",&n,&ar[n]);
Вы думаете, что будет введено целое n и n - ный элемент масива ar ?
Это очень маловероятно. Скорее всего, все аргументы scanf будут вычислены до того, как операция будет вызвана на выполнение. Подобных побочных эффектов в языке масса.
Другая "особенность"
char
str[50]="qwertyuio";
int a=3;str[++a]=str[++a]=' ';
cout<<str<<"\n";
str[a++]=str[a++]=' ';
cout<<str<<"\n";
Результат:
qwe tyuio
qwert uio
По логике вещей должны быть добавлены два пробела. Но у C своя логика, так что это не ошибка компилятора, а особенность языка.
int i=0,ar[2]={10,11};
i=ar[i++];// А кто сразу скажет чему равно значение i
Хотите еще ? Формат вывода зависящей от типа:
short int x=55;
printf("%d\n",x);
Если заменить short int на longt int, то придется менять и printf("%d\n",x) на printf("%D\n",x)
Пример: предположим, что вместо i<=100 разработчик написал i=100 при синтаксисе C/C++
for (i=0; i=100; i++)
Цикл будет выполняться вечно (вместо 101 раза) т.к.
Отсутствует логический тип данных.
Выраженние i=100 равно 100(т.е. по не ноль - истина).
Поскольку C включает в себя элементы не только процедурного, но и функционального программирования такая конструкция вполне правильна и логична.
По мере развития в C включалось все больше возможностей Изначально язык не имел средств даже для описания констант. Когда Си стал применяться для решения серьезных задач, к нему добавили так называемые "директивы препроцессора", такие, как #define и #include.