Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
#include <iostream>
int main(int argc, char**argv)
{
cout << "Hello world!\n";
return 0;
}
Убрать параметры функции main, заменить int на void и убрать return — и всё уже совсем не страшно.И поймать предупреждения компилятора. Отличный план, показывать некорректную программу на первом же занятии. А #include вы тоже уберёте? И cout? И \n? Или сразу объясните, что есть препроцессор, который может включать заголовочные файлы, про которые надо тоже рассказать. Итого чтобы просто перейти к объяснению второй строки программы вам понадобится минимум два часа учебного времени, в ходе которого больше половины студентов крепко уснёт.
int main() { /* ... */ }
int main(int argc, char* argv[]) { /* ... */ }main()
{
printf("Hello world!\n");
}
main () {
puts ("Hello world!");
}
(zyx-desktop:zyx:~) 1 % echo $'main(){puts("Hello word!");}' | clang -x c -
<stdin>:1:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
main(){puts("Hello word!");}
^~~~
<stdin>:1:8: warning: implicit declaration of function 'puts' is invalid in C99 [-Wimplicit-function-declaration]
main(){puts("Hello word!");}
^
2 warnings generated.
(zyx-desktop:zyx:~) 1 % echo $'main(){puts("Hello word!");}' | gcc -x c -Wall -
<stdin>:1:1: предупреждение: по умолчанию возвращаемый тип функции - «int» [-Wreturn-type]
<stdin>: В функции «main»:
<stdin>:1:1: предупреждение: неявная декларация функции «puts» [-Wimplicit-function-declaration]
<stdin>:1:1: предупреждение: control reaches end of non-void function [-Wreturn-type]
Кстати, видите первое предупреждение? Функция без возвращаемого типа должна возвращать int. А что возвращаете вы? Я не думаю, что приводить в качестве первого примера не корректную программу — хорошая идея.(zyx-desktop:zyx:~) 1 % echo $'main(){puts("Hello word!");}' | clang -x c++ -
<stdin>:1:1: error: C++ requires a type specifier for all declarations
main(){puts("Hello word!");}
^~~~
<stdin>:1:8: error: use of undeclared identifier 'puts'
main(){puts("Hello word!");}
^
2 errors generated.
(zyx-desktop:zyx:~) 1 % echo $'main(){puts("Hello word!");}' | gcc -x c++ -
<stdin>: В функции «int main()»:
<stdin>:1:26: ошибка: нет декларации «puts» в этой области видимостиНа этот раз gcc не молчит даже без -Wall. ofstrCfg << cbxLeft1When->ItemIndex << std::endl;[bcc32 Error] Main.cpp(2727): E2335 Overloaded 'endl' ambiguous in this context
extern _cdecl int printf(const char *, ...);нельзя и не нужно объять необъятное на первом же занятии.На первом занятии не должно быть необъятного. Студент должен чётко понимать, что делает каждая строка, и какие последствия она несёт. Иначе это не обучение программированию, а курсы заклинателей компьютера.
scala HelloWorld.scala, то минимальный пример будет выглядеть так:println("Hello world!")
Одно делать быть сложным, а другое не понимать вообще
Для того чтобы выбрать C++ в качестве первого языка программирования существует четыре причины:И начать с красно-чёрных деревьев, да.
…
4. STL.
Стоит отметить такой важный момент, как не принудительное ООП. То есть данный подход к программированию применяется тогда, когда это удобно, и его можно смешивать, например, с функциональным программированием.
чем отличается символ от строки
В плюсах появилось функциональное программирование?
Char — не символ (потому, что юникод).
Указатель на первый из них — не строка.
Смысл начинать с него?
«The width of wchar_t is compiler-specific and can be as small as 8 bits. Consequently, programs that need to be portable across any C or C++ compiler should not use wchar_t for storing Unicode text. The wchar_t type is intended for storing compiler-defined wide characters, which may be Unicode characters in some compilers.»
Нет, wchar_t — legacy, которое часто путают с юникодом.
Это — два совершенно разных языка. С на порядки проще.
Ну да, шаблоны в начале обучения программированию — прекрасная идея.
В них есть веская причина использовать эти суррогатные пары.
Метапрограммирование на шаблонах — чистой воды функциональщина.
В плюсах появилось функциональное программирование? А можно и мне его отсыпать?
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include <errno.h>
int strrev(char *const target, const char *const source)
{
const size_t length = (source) ? strlen(source) : 0;
size_t offset = 0;
size_t have, nextlen;
wctype_t combining;
mbstate_t state;
wchar_t next;
/* Invalid parameters? */
if (!target)
return errno = EINVAL;
/* NULL or empty source string? */
if (length < 1) {
*target = '\0';
return 0;
}
/* Get the combining character type. */
combining = wctype("combining");
/* Clear shift state. */
memset(&state, 0, sizeof state);
/* Length of the initial wide character. */
nextlen = mbrtowc(&next, source, length, &state);
if (nextlen < 1 || nextlen > length)
return errno = EILSEQ;
/* Character loop. */
while (offset < length) {
/* Take the next character. */
have = nextlen;
/* Scan for the next character. */
while (offset + have < length) {
/* Convert next character (so we can find out its class) */
nextlen = mbrtowc(&next, source + offset + have, length - offset - have, &state);
if (nextlen < 1 || nextlen > length - offset - have)
return errno = EILSEQ;
/* Not a combining character? */
if (!iswctype((wint_t)next, combining))
break;
/* Combining characters are grouped with the previous character. */
have += nextlen;
}
/* Copy the wide character, including any combining characters that follow it. */
memcpy(target + length - offset - have, source + offset, have);
offset += have;
}
/* Terminate target. */
target[length] = '\0';
return 0;
}std::string s("foo");
std::reverse(begin(s), end(s));s это строка в UTF-8?#include <string>
#include <algorithm>
#include <iostream>
int main() {
std::string s("фыва");
std::cout << s << std::endl;
std::reverse(std::begin(s), std::end(s));
std::cout << s << std::endl;
}
фыва
°вЋфÑ
QString внутри юникодовая, содержит 16-битные символы с суррогатными парами.рассмотрим процесс выбора первого языка исключительно для студентов профильных специальностей
наличие заинтересованности и определённого склада ума у студентов. Такие студенты чаще всего уже пробовали программировать, а возможно даже и написали сайт/игрушку.По своему опыту учёбы в ВУЗе хочу заметить, что та категория студентов (их меньшинство), которая ещё до прихода в ВУЗ плотно сидит на различных… языках и олицетворяет собой образ того, кого на западе называют Geek; судя по всему именно к ним изображён ваш посыл; так вот они всегда будут зевать на лекциях по любому языку программированию (у нас так и было) — им это всё уже известно, а что неизвестно — они сами быстро могут освоить в комфортной домашней обстановке, нежели слушать лекционное разжёвывание «для всех».
var x = [{x: 1, y:2}, {x:3, z:4}];
for(var i=0; i<x.length; i++) {
console.log(x[i].x);
}
data MyType = Int n | String s
myFilter :: [MyType] -> [MyType]
...
var tree = { child:[
{data:1},
{ child:[
{data:2},
{data:3}
]}
]};
val tree = 1.node( 2.leaf, 3.leaf)
println(tree.drawTree)
// 1
// |
// +- 2
// |
// `- 3
datatype tree = Data of (int * tree list)
val t = Data (1, [
Data (2, []),
Data (3, [])
])
В таком случае подход со статической типизацией всего лишь делает явными все ваши неявные контракты на структуры данных (которые вы предлагаете держать в уме).
Объекты в JS и есть map.
Подход со статической типизацией требует изучения системы типов, а это чуть ли не самое сложное в современных языках.
for(var i=0; i<x.length; i++) когда во всех нормальных языках уже есть вменяемые конструкции для этого (а в JS конструкция for(var x in xs) вообще не понятно для кого придумана). Приходится совершать кучу лишних приседаний вместо того, чтобы сосредоточится на задаче. Про области видимости, мутабельность везде и во всем и монструозный синтаксис лямбд лучше вообще не вспоминать.То есть вместо общей концепции вы предлагаете изучать конкретную реализацию? Да еще и довольно не наглядную?
Я не предлагаю изучать систему типов досконально. Достаточно базового уровня — как структуры контейнера данных и методов.
Кстати в JS уже есть давно Array.prototype.forEach.
"2" == 2 нет почти ни где. Что такое семантическое сравнение лучше просто не заикаться.case class Tree[T](data: T, children: Seq[Tree[T]])
def height(tree: Tree[_]): Int =
if (tree.children.isEmpty) 1
else 1 + tree.children.map{height}.max
"2" * 2 == 4, a "2" + 2 == "22"?Не нужно просто этого писать.
кучу дополнительных конструкций
val xs = List[{def x: Int}](new { val x = 1; val y = 2 }, new {val x = 3; val z = 4})
xs.map{ _.x }
// List[Int] = List(1, 3)
val xs = List(Map('x -> 1, 'y -> 2), Map('x -> 3, 'z -> 4))
xs.map{ _('x) }
// List[Int] = List(1, 3)
for(var i=0; i<x.length; i++) {
console.log(x[i].y); // bang!
}
for(var i=0; i<x.length; i++) {
if(x[i].y) {
console.log(x[i].y); // OK
}
}
if('y' in x[i])
Вот зачем мне сразу инициализировать переменную, если я ещё не знаю, чем её буду инициализировать?
SomeInterface si;
if (someVar extends SomeSpecialClassWithInterfaceImplementation)
si = someVar;
else
si = SomeManufacture.getInstance();
val si =
if (condition) valueOnTrue
else valueOnFalse
Аналоги jsfiddle для любого языка есть
onlinegdb.com
onecompiler.com
- привести. 1 - "2" в JS — ИМХО, бред сивой кобылы в JS.1 - "2" вернет -1, например.Не используйте слова «строгая» в отношении к типизации. Типизация бывает статическая — при компиляции и динамическая — во время выполнения программы.
А Pascal подходит для первоначального обучения? а Basic?
Вообще, близость к машинной архитектуре — миф со времён софта, умевшего только 1 ядро одного процессора на одной машине и не представлявшего о GPGPU.
Так выбирать же можно не только между ними. Есть тот же Python, использующийся в MIT. Чем мы хуже?
В питоне строгая типизация, есть типы (причём базовых типов достаточно) и можно объяснить типовую безопасность.
Это в C можно привести указатель на число к указателю на строку, там типизация слабая. Динамичность тут ни при чём.
В смысле с перфокарт и архитектуры PDP-8?
Мы не можем гарантировать, что базовая архитектура останется той же даже 10 лет, не говоря о прочих сроках.
И, опять же, начиная с вымерших языков, в которых половину времени приходится писать очевидный как нам, так и компилятору синтаксический мусор вместо тех же map/fold* или list comprehension, вряд ли можно до конца курса успеть понять потоки (которые ГОРАЗДО сложнее и ГОРАЗДО более применимы, чем основы паскаля уже сейчас), не говоря об асинхронном программировании и хотя бы базовых представлениях о кластерах. И те же лямбды сейчас используют все, а не только освоившие нужный мат. аппарат (и зачастую получается неплохо).
{ X is array of LongInt }
Procedure QuickSort ( Left, Right : LongInt );
Var
i, j : LongInt;
tmp, pivot : LongInt; { tmp & pivot are the same type as the elements of array }
Begin
i:=Left;
j:=Right;
pivot := X[(Left + Right) shr 1]; // pivot := X[(Left + Rigth) div 2]
Repeat
While pivot > X[i] Do i:=i+1;
While pivot < X[j] Do j:=j-1;
If i<=j Then Begin
tmp:=X[i];
X[i]:=X[j];
X[j]:=tmp;
j:=j-1;
i:=i+1;
End;
Until i>j;
If Left<j Then QuickSort(Left,j);
If i<Right Then QuickSort(i,Right);
End;def qsort(list):
if not list:
return []
else:
pivot = list[0]
less = [x for x in list if x < pivot]
more = [x for x in list[1:] if x >= pivot]
return qsort(less) + [pivot] + qsort(more)(нет в них ничерта сложного даже для новичка)
foo = bar.boo(foo) + faz;Prerequisites
Math 1A is a corequisite for 61A. (That is, it may be taken concurrently.)
There is no formal programming-related prerequisites for admission to 61A.
И да, можете привести ссылку хоть на один серьёзный курс, использующий pascal как первый язык в 21 веке?
> Лекции, которые вы предоставили — это не «программирование с нуля».
Наглейшая ложь.
Язык для обучения там, кстати, рекомендуют. Этот. Это — CS10, который проще.
Программирование — об абстракциях, а не многословности и типах вроде int/long.
Вспоминаю студенческие годы, ...
Преимущества C++ как первого языка для обучения программированию