Руководство C для начинающих

1- Введение

Это статья основана на:
  • Eclipse 4.5 (MARS)

2- Что нужно чтобы начать с  C/C++ 

В статьях руководства  C/C++ на вебсайте  o7planning мы используем  Eclipse IDE. Вам нужно установить и конфигурировать  Eclipse и среду  C/C++ перед началом. Можете посмотреть инструкцию по ссылке:

3- Различие C и C++

Вам нужно иметь общее понятие для различия  C и  C++.
C это язык который вышел раньше, и является объектно-ориентированным языком, он легко используется и запускается на операционных системах. C++ разработан после расширения из C он принес понятие объектно-ориентированное программирование, C это платформа  C++, и  C++ не был разработан для замены  C, его библиотеки намного расширились.
Процедурно-ориентированное программирование здесь означает: Исходные файлы (Содержащий ваш код) будет содержать функции. При этом объектно-ориентированный файл содержит класс и в классе содержатся методы. Чтобы вызвать метод в классе вам нужно создать объект класса и потом вызвать метод через этот объект, при этом с процедурно-ориентированным вы можете вызвать функцию напрямую.
В данной статье я покажу вам как работать на C. А про  C++ будет рассказано в другой статье.

4- Создать Project для начала с C

Если вы работаете с: Windows 64bit + Eclipse 64bit + Java64bit, вам нужно открыть  Eclipse с авторизацией  Administrator, есть одна проблема это  Eclipse не печатает  message на экран  Console в случае запуска в обычном моде.
  • File/New/Other..
В данной статье я покажу вам как программировать C ( C++ будет инструкция в другой статье). Но project который мы создаем здесь это  C++, но мы будем использовать только библиотеки C.
Ввести название  Project:
  • CBasicTutorial
Project создан, действительный код (code) примера этого  HelloWorld это   C++.  Но еще не нужно обращать на него внимания.
Компилировать project (Compile project).
Project успешно компилирован.
Далее вам нужно конфигурировать чтобы запустить project прямо на  Eclipse, это очень важно.
Запустить пример  HelloWorld
Или:
Результаты запуска примера:
OK! Все работает.

5- Характеристика C и внимание при выполнении

Когда программа  C запущена, она будет искать функцию  main() для выполнения, например выполнение  main() примера  HelloWorld выше.

Программа  может иметь много исходных файлов, каждый исходный файл может иметь несколько функций. Но она позволяет только одной функции  main() на всем вашем Project.
Выше вы создали файл  CBasicTutorial.cpp который имеет функцию  main(), теперь создайте другой файл для практики например PrimitiveExample.cpp и с функцией  main() вам нужно переименовать функцию  main() в  CBasicTutorial.cpp на другое название чтобы не было конфликта и вы могли компилировать project, потом можно практиковать то, что написано в  PrimitiveExample.cpp.
 
По-моему в процессе практики вам нужно выбрать следующее переименование:
  • CBasicTutorial.cpp
    • main()  ==> mainCBasicTutorial()

6- Структура программы C

Я создам новый файл  cpp для изображения и объяснения структуры программы C.
В  Eclipse выберите:
  • File/New/Other...
Ввести:
  • Source file: MyFirstExample.cpp
  • Template: Default C source temple
Создан исходный файл, в нем ничего нет.
Вы напишем кода для этого исходного файла:
Примечание: Поменяйте название функции main исходного файла  CBasicTutorial.cpp на  mainCBasicTutorial так как project в  C только позволяет одну функцию main во всем Project.
MyFirstExample.cpp
// Объявить использование IO библиотеки стандарта stdio.h
// (Standard IO / Standard Input Output)
#include<stdio.h>

int main() {

	// printf является функцией библиотеки stdio.h
	// Это функция для распечатки строки текста на экран Console.
	// \n это символ новой строки
	printf("Hello!, This is your first C example.\n");

	// Распечатать строку объявления завершения приложения.
	printf("Exit!");

	// Функция возвращает 0.
	return 0;

}
Запуск примера:
Результаты запуска примера:
Есть некоторые примечания: Есть некоторые функции в библиотеке  conio.h в  C которые не поддерживаются в  C++. Например  getch() - Является функцией паузы программы до тех пор, пока пользователь не введет новый символ, только тогда продолжает работать дальше. Поэтому в данной статье я пытаюсь не использовать такие функции в примерах.
#include<conio.h>

int main() {

	// Сделать что-то здесь ....
	// Остановить программу здесь,
	// ждем когда пользователь введет любой символ, тогда продолжается запуск.
	// (Данная функция непольностью поддерживается)
	getch();

	// Сделать дальше что-то здесь.
}

7- Вид данных в C

7.1- Целое число

Type Storage size Value range Format
char 1 byte -128 to 127 or 0 to 255 %c
unsigned char 1 byte 0 to 255 %c
signed char 1 byte -128 to 127 %s
int 2 or 4 bytes -32,768 to 32,767 or -2,147,483,648 to 2,147,483,647 %d
unsigned int 2 or 4 bytes 0 to 65,535 or 0 to 4,294,967,295 %u
short 2 bytes -32,768 to 32,767  
unsigned short 2 bytes 0 to 65,535  
long 4 bytes -2,147,483,648 to 2,147,483,647 %ld
unsigned long 4 bytes 0 to 4,294,967,295  

7.2- Число с плавающей точкой (Floating point type)

Вид данных Размер хранение Диапазон значений Десятичная дробь
float 4 byte 1.2E-38 to 3.4E+38 6 знаков после запятой
double 8 byte 2.3E-308 to 1.7E+308 15 знаков после запятой
long double 10 byte 3.4E-4932 to 1.1E+4932 19 знаков после запятой

7.3- Пример

PrimitiveExample.cpp
// Объявить использование IO библиотеки стандарта stdio.h
// (Standard IO / Standard Input Output)
#include <stdio.h>

// Объявить использование библиотеки float.h
#include <float.h>


int main() {

	// Функция sizeof(type)
	// возвращает количество байтов необходимых для хранения этого вида данных.
	printf("Storage size for float : %d \n", sizeof(float));

	// FLT_MIN является константой, самое малое значение вида float.
	// Данная константа будет определена в библиотеке float.h
	printf("Minimum float positive value: %E\n", FLT_MIN);

	// FLT_MAX является константой, самое большое значение вида данных float.
	// Данная константа будет определена в библиотеке float.h
	printf("Maximum float positive value: %E\n", FLT_MAX);

	// FLT_DIG является константой, максимальное количество позиций дробной части.
	// Данная константа будет определена в библиотеке float.h
	printf("Precision value: %d\n", FLT_DIG);

	return 0;

}
Результаты запуска примера:

8- Команда ветки в C (if - else if - else)

if это команда проверки условия в C. Например: Если  a > b то сделать что-то ....
Общие операторы сравнивания:
Оператор Значение Пример
> Больше 5 > 4 правильно (true)
< Меньше 4 < 5 правильно  (true)
>= Больше или равно 4 >= 4 правильно  (true)
<= Меньше или равно 3 <= 4 правильно  (true)
== Равно 1 == 1 правильно  (true)
!= Неравно  1 != 2 правильно  (true)
&& И  a > 4 && a < 10
|| Или  a == 1 || a == 4
// Синтаксис
if ( condition ) {

	// Сделать что-то здесь.
}
Пример:
// Пример 1:
if ( 5 < 10 ) {
	printf( "Five is now less than ten");
}

// Пример 2:
if ( true ) {
	printf( "Do something here");
}
Полная структура  If-Else if-Else:
// Заметьте, что максимум запустится только один блок.
// Программа проверяет условия сверху вниз.
// При неправильном условии, определенный блок будет запущен,
// и программа не проверяет дальше остальные условия.
...

// Если условие 1 верное, то ...
if ( condition1) {

	// Сделать что-то при верном условии 1.
}
// Наоборот, если условие 2 верное, то  ....
else if( condition2 ) {

	// Сделать что-то при верном условии 2
	// (Условие 1 неверное).
}
// Наоборот, если условие N  верное, то...
else if( conditionN ) {
	// Сделать что-то при верном условии N 
	// (Условия выше неверные).
}
// Остальные случаи.
else {
	// Сделать что-то здесь.
}
Пример:
IfElseExample.cpp
// Объявить использование IO библиотеки стандарта stdio.h
// (Standard IO / Standard Input Output)
#include <stdio.h>

int main_IfElseExample() {

	// Объявить число, представляющее ваш возраст.
	int age;

	printf("Please enter your age: \n");

	// Иногда использование printf не сразу распечатывает ваше сообщение.
	// Использовать fflush(stdout) чтобы сразу распечатать на экране Console.
	// Примечание: stdout является переменной потока (stream) записанный на экране Console
	// (Она определена в библиотеке stdio.h)
	fflush (stdout);

	// Функция scanf ждет когда вы введете текст с клавиатуры
	// (И нажмете Enter для завершения).
	// Она сканирует число (Определенное параметром %d)
	// и прикрепляет переменную age.
	scanf("%d", &age);

	// Проверка, если age меньше 80, то ...
	if (age < 80) {
		printf("You are pretty young");
	}

	// Наоборот, если возвраст в рамках 80, 100, то
	else if (age >= 80 && age <= 100) {
		printf("You are old");
	}
	// Наоборот (Остальные случаи)
	else {
		printf("You are verry old");
	}

	return 0;
}
Запуск примера:
Программа печатает строку  "введите число", введите 70 и нажмите  Enter.
Результаты:
Вы можете перезапустить пример и ввести другие числа, чтобы посмотреть результаты.

9- Команда Switch

Синтаксис команды  switch:
// Использовать switch, чтобы проверить значение одной переменной.
switch ( a_variable ) {
	case value1:
		// Сделать что-то здесь, если значение переменной == value1
		break;
	case value2:
		// Сделать что-то здесь,если значение переменной == value2
		break;

	default:
		// Сделать что-то здесь
		// если значение переменной не принадлежит значениям перечисленным выше.
		break;
}
SwitchExample.cpp
#include <stdio.h>

int main() {

	// Просит пользователя выбрать 1 вариант.
	printf("Please select one option:\n");

	printf("1 - Play a game \n");
	printf("2 - Play music \n");
	printf("3 - Shutdown computer \n");

	fflush (stdout);

	// Объявить переменную 'option'.
	int option;

	// Функция scanf ждет, когда вы вводите текст с клавиатуры
	// (И нажмете enter для завершения).
	// Она сканирует число (Определенное параметром %d)
	// Конвертирует в integer и прикрепляет переменную option.
	scanf("%d", &option);

	// Проверка значения 'option'.
	switch (option) {

	case 1:
		printf("You choose to play the game \n");
		break;
	case 2:
		printf("You choose to play the music \n");
		break;
	case 3:
		printf("You choose to shutdown the computer \n");
		break;
	default:
		printf("Nothing to do...\n");
		break;
	}

	fflush(stdout);

	return 0;

}
Результат запуска примера (В случае введения числа 2 и нажать на  Enter).

Примечание:

Есть один вопрос, когда вы устанавливаете команду  break в данном случае что это значит?

break в данном случае сказали программе выйти из switch. В случае если вы не используете  break программа продолжит блок команды в 'case' внизу (или так же блок default) пока не встретит  break, даже если значение переменной в том случае отличается от значения в 'case'.
Посмотрим изображенный пример:
SwitchExample2.cpp
#include <stdio.h>

int main() {

	// Объявить переменную option и прикрепить к ней значение 3.
	int option = 3;

	printf("Option = %d \n", option);

	// Проверить значение option
	switch (option) {

	case 1:
		printf("Case 1 \n");
		break;
	case 2:
		printf("Case 2 \n");
		// No break
	case 3:
		printf("Case 3 \n");
		// No break
	case 4:
		printf("Case 4 \n");
		// No break
	case 5:
		printf("Case 5!!! \n");
		break;
	default:
		printf("Nothing to do...\n");
		break;
	}

	fflush (stdout);

	return 0;

}
Результат запуска примера:

10- Цикл в C

Цикл используется для повторного запуска блока команд. Он заставляет вашу программу повторно выполнять один блок команд много раз, это один из основных обязанностей в программировании. 
C поддерживает 3 разных вида циклов:
  • FOR
  • WHILE
  • DO WHILE

10.1- Цикл FOR

Структура цикла FOR:
// variable_initialization: Инициализировать переменную.
// condition: Условие.
// variable_update: Обновить новое значение переменной.
for ( variable_initialization; condition; variable_update ) {
	// Необходимо выполнить коды при верном условии.
}
Пример:
// Пример 1:
// Создать переменную x  и прикрепить к ней значение 0.
// Условие проверки x < 5.
// Если x < 5 верно, то запускается блок команды.
// После каждого повтора (iteration) значение x снова обновляется,
// В данном примере, при каждом повторе, значение x увеличивается на 1.
for (int x = 0; x < 5; x = x + 1) {
	// Сделать что-то здесь, если x < 5 верно.
}

// Пример 2:
// Создать переменную x  и прикрепить к ней начальное значение 2
// Условие проверки x < 15
// Если x < 15 верно, то запускается блок команды.
// После каждого повтора (iteration) значение x  увеличивается на 3.
for (int x = 2; x < 15; x = x + 3) {
	// Сделать что-то здесь, если x < 15 верно.
}
ForLoopExample.cpp
#include <stdio.h>

int main() {

	printf("For loop example\n");

	// Иногда, используя printf не сразу распечатывается ваше сообщение.
	// Используйте fflush(stdout), чтобы гарантировать сообщение распечатывается моментально.
	// Примечание: stdout является переменной потока (stream) распечатанная на экране Console
	// (Она определена в библиотеке stdio.h).
	fflush (stdout);

	// Создать переменную x и прикрепить к ней начальное значение 2.
	// Условие проверки x < 15
	// Если x < 15 верно, то запускается блок команды.
	// После каждого iteration, значение x увеличивается на 3.
	for (int x = 2; x < 15; x = x + 3) {
		printf("\n");
		printf("Value of x = %d \n", x);
		fflush(stdout);
	}
	return 0;

}
Результат запуска примера:

10.2- Цикл WHILE

Синтаксис цикла WHILE:
while ( condition ) {

	// При верном условии, выполнить блок команды.
}
Пример:
// Пример 1:
// Объявить переменную x.
int x = 2;

while ( x < 10) {
	// Сделать что-то здесь если x < 10 верно.
	// ....
	// Обновить новое значение переменной x.
	x = x + 3;
}
WhileLoopExample.cpp
#include <stdio.h>

int main() {

	printf("While loop example\n");

	fflush (stdout);

	// Создать переменную x vи прикрепить ее начальное значение 2
	int x = 2;

	// Условие проверки x < 10
	// Если x < 10 верно, то выполняется блок команды.
	while (x < 10) {
		printf("Value of x = %d \n", x);

		x = x + 3;
		fflush(stdout);
	}
	return 0;

}
Результаты запуска примера:

10.3- Цикл DO WHILE

Синтаксис цикла DO-WHILE
// Особенностью цикла 'do-while' является выполнение блока команды минимум 1 раз.
// После каждого повтора (iteration) он проверяет условие, чтобы выполнить следующий повтор.
do {

	// Сделать что-то здесь.
}while ( condition );  // Note: Need ';'.
DoWhileLoopExample.cpp
#include <stdio.h>

int main() {

	printf("Do-While loop example\n");

	fflush (stdout);

	// Создать переменную x и прикрепить ей значение 2.
	int x = 2;

	// Особенностью цикла 'do-while' является выполнение блока команды минимум 1 раз.
	// Потом проверяет условие
	// чтобы решить, выполнять следующий блок команды, или нет.
	do {
		printf("Value of x = %d \n", x);

		x = x + 3;
		fflush(stdout);
	} while (x < 10); // Note: ==> Need ';'

	return 0;

}
Running the example:

10.4- Команда break в цикле

break является командой, которая может находиться в блоке команд одного цикла. Это команда завершения безусловного цикла.
BreakExample.cpp
#include <stdio.h>

int main() {

	printf("Break example\n");

	fflush (stdout);

	// Создать переменную x и прикрепить ей значение 2.
	int x = 2;

	while (x < 15) {

		printf("----------------------\n");
		printf("x = %d \n", x);

		// Проверить если x = 5, то выйти из цикла.
		if (x == 5) {
			break;
		}
		// Увеличить значение  x на 1 (Написать кратко для x = x + 1).
		x++;
		printf("x after ++ = %d \n", x);

	}
	return 0;

}
Результаты запуска примера:

10.5- Команда continue в цикле:

continue это команда, которая может находиться в одном цикле, при встрече с командой continue программа пропустит команды в одном цикле и внизу  continue и начнет новый цикл.
ContinueExample.cpp
#include <stdio.h>

int main() {

	printf("Continue example\n");

	fflush (stdout);

	// Создать переменную x и прикрепить ей значение 2.
	int x = 2;

	while (x < 7) {

		printf("----------------------\n");
		printf("x = %d \n", x);

		// % является оператором деления с остатком.
		// (Remainder operator).
		// Если x является четным числом, то пропустить строки команд ниже
		//  в 'continue', продолжить новый шаг повторения (если есть).
		if (x % 2 == 0) {
			// Увеличить значение x на 1 (Кратко написать для x = x + 1;).
			x++;
			continue;
		} else {
			// Увеличить значение x на 1 (Кратко написать для x = x + 1;).
			x++;
		}
		printf("x after ++ = %d \n", x);

	}
	return 0;

}
Результаты запуска примера:

11- Массив в C

11.1- Одномерный массив

Это изображение одномерного массива с 5 элементами, элементы индексированы от 0 до 4.
Синтаксис объявления одномерного массива:
// Способ 1:
// Объявить массив чисел int, определяющий элементы.
int years[] = { 2001, 2003, 2005, 1980, 2003 };

// Способ 2:
// Объявить массив с 5 элементами,
// определяющий значение 3 первым элементам.
int age[5] = { 20, 10, 50 };

// Способ 3:
// Объявить массив чисел float, определяющий количество элементов.
// (Размер 3).
float salaries[3];
ArrayExample1.cpp
#include <stdio.h>

int main() {

	// Способ 1:
	// Объявить массив с элементами.
	int years[] = { 2001, 2003, 2005, 1980, 2003 };

	// Написать количество нужных байтов для хранения вида int.
	printf("Sizeof(int) = %d \n", sizeof(int));

	// Количество байтов нужных для хранения данного массива.
	printf("Sizeof(years) = %d \n", sizeof(years));

	int arrayLength = sizeof(years) / sizeof(int);

	printf("Element count of array years = %d \n\n", arrayLength);

	// Использовать цикл for чтобы распечатать элементы массива.
	for (int i = 0; i < arrayLength; i++) {
		printf("Element at %d = %d \n", i, years[i]);
	}

	fflush (stdout);

	// Способ 2:
	// Объявить массив с размером 3.
	float salaries[3];

	// Прикрепить значения элементам.
	salaries[0] = 1000;
	salaries[1] = 1200;
	salaries[2] = 1100;

	return 0;

}
Результат запуска примера:

11.2- Двумерный массив

Это изображение двумерного массива
Синтаксис объявления двумерного массива:
// Объявить двумерный массив определяющий элементы.
// 3 строки & 5 столбцов
int a[3][5] = { { 1, 2, 3, 4, 5 },
		        { 0, 3, 4, 5, 7 },
				{ 0, 3, 4, 0, 0 } };

// Объявить двумерный массив,
// Определить количество строк, столбцов.
int a[3][5];
ArrayExample2.cpp
#include <stdio.h>

int main() {

	// Объявить двумерный массив (3 строки, 5 столбцов)
	int a[3][5] = { { 1, 2, 3, 4, 5 }, { 0, 3, 4, 5, 7 }, { 0, 3, 4, 0, 0 } };

	// Использовать цикл for чтобы распечатать элементы массива.
	for (int row = 0; row < 3; row++) {
		for (int col = 0; col < 5; col++) {
			printf("Element at [%d,%d] = %d \n", row, col, a[row][col]);
		}
	}

	fflush (stdout);

	return 0;
}
Результаты запуска примера:

12- Указатель (Pointer)

Указатель (Pointer) это переменная с значением адреса другой переменной, например, прямой адрес местоположения памяти. Как и любая переменная или константа, вам нужно объявить указатель перед тем как использовать его чтобы хранить адрес любой переменной. Синтаксис объявления указателя:
type *variable-name;
Пример:
// Объявить переменную вида int.
int var = 120;

// Объявить указатель (pointer) (указывающий на адрес вида int).
int *ip;

// Прикрепить значение к ip (указывающий на адрес переменной 'var').
ip = &var;

// Использовать * чтобы получить доступ в значение переменной, к которой указывает указатель.
int var2 = *ip;
PointerExample.cpp
#include <stdio.h>

int main() {

	// Объявить переменную
	int var = 120;

	// Объявить указатель (Pointer).
	int *ip;

	// Прикрепить адрес переменной 'var' указателю.
	ip = &var;

	// Написать адрес переменной 'var'.
	printf("Address of var variable: %x \n", &var);

	// Написать сохраненный адрес в переменной 'ip'.
	printf("Address stored in ip variable: %x \n", ip);

	// Доступ в цену переменной, к которой указывает указатель.
	printf("Value of *ip variable: %d\n", *ip);

	fflush (stdout);

	int var2 = *ip;

	return 0;

}

12.1- NULL Pointer

NULL это константа предопределенная в некоторых библиотеках  C. Когда вы объявляете указатель но не прикрепляете к нему определенное значение, он будет указывать на случайный регион памяти. В некоторых случаях вы можете объявить указатель и прикрепить к нему напрямую значение  NULL. Посмотрим пример:
NULLPointerExample.cpp
#include <stdio.h>

int main() {

	// Объявить указатель (Pointer).
	// Не прикреплять никакого значения данному указателю.
	// (Он указывает на случайный регион памяти).
	int *pointer1;

	// Распечатать адрес pointer1
	printf("Address of pointer1 is %x \n", pointer1);

	// Проверить pointer1 является не NULL.
	if (pointer1) {
		// Распечатать значение региона, куда указывает pointer1.
		printf("Value of *pointer1 is %d \n", *pointer1);
	}

	// Объявить переменную указателя (Pointer).
	// Указать к позиции NULL (Указать никуда).
	int *pointer2 = NULL;

	// Написать адрес pointer2.
	printf("Address of pointer2 is %x \n", pointer2);

	// Если pointer2 является NULL написать оповещение.
	if (!pointer2) {
		printf("pointer2 is NULL");
	} else {
		// ПРИМЕЧАНИЕ:
		// Если pointer2 NULL получение доступа к значению *pointer2
		// будет ошибкой и остановит программу.
		printf("Value of *pointer2 is %d \n", *pointer2);
	}

	fflush (stdout);

	return 0;
}
Результат запуска примера:

13- Функция (Function)

  • TODO