Показать полную графическую версию : нужны задания практические по С
вспоминаю и изучаю дальше - С, самостоятельно. Дайте какие нибудь задания пожалуйста, а лучше несколько по возрастающей (по сложности) . Или посоветуйте где можно эти задания найти 8) Уровень начинающего.
Diseased Head
17-11-2006, 19:11
bool
Мне это тоже интересно.
Но у меня такое ощущение что все забыли про C. Про структурное программирование забыли. И непонятно, почему?
Ведь ОО языки предназначены для написания, больших по размеру программ (ну можно и средних). А писать на C++ (и др. ООЯ) маленькие проги это дибилизм. Уж не говоря о C# и Java. Эти мне кажется вобще предназначены только для прикладух и под сеть, а системные проги на них писать, по моему, изврат.
Или я не прав?
вспоминаю и изучаю дальше - С, самостоятельно
Чистый C сейчас практически нигде не используется, посему советую (лично моё мнение) взяться за C++... Даже фирмы, которые писали на чистом C, скажем, драйвера или программы прошивки для всяких устройст (т.е. системное низкоуровневое программирование), сейчас переходят на C++. Потому что сейчас уже разницы практически нет, что мы напишем прогу с использованием классов и конструкторов на C++, что с использованием переменных и инициализирующих функций (вместо конструкторов) на чистом C. А вернее, машинный код после компиляции C-программы ничуть не быстрее и не короче, чем после компиляции аналогичной C++-программы (а эти параметры - скорость и размер кода - в системном программировании играют ведущую роль). Раньше то, возможно, и была. Но сейчас компиляторы и оптимизаторы сделали своё дело.
Это о скорости выполнения кода и о его размере. Что касается простоты, удобства и эффективности, то верх берёт, однозначно, C++...
Но у меня такое ощущение что все забыли про C. Про структурное программирование забыли. И непонятно, почему?
С++ - не чисто объектно-ориентированный язык (в отличие, например, от C#). C++ проектировался как язык общего назначения с уклоном в сторону системного программирования и поддерживающий несколько парадигм программирования, куда наряду с парадигмой ООП входит и парадигма процедурного программирования. Никакой стиль программирования язык не навязывает, он всего лишь предоставляет удобные средства для использования какой-либо парадигмы. Т.е. С++ не заменяет C, а всего лишь добавляет поддержку абстракции данных, объектно-ориентированного и обобщённого программирования (его главные преимущества перед традиционным C).
Т.е. на C++ запросто можно написать структурную программу без использования классов и конструкторов/деструкторов (если нравится). На C же ООП-программа пишется довольно сложно (поддержки ООП то нет)...
Таким образом, системные программы на C++ пишутся так же легко, как и на чистом C. Чего не скажешь, например, о C#. На C# тоже можно писать системные программы, но это неоправданно сложно и неэффективно, поскольку C# - полностью объектно-ориентированный язык (там даже функция main принадлежит классу) и заточенный именно на ООП. Другие парадигмы он не поддерживает...
CyraxZ, а почему на C# неэффективно писать системные программы? Тот же Visual Studio 2005 всё равно сначала переводит программу с поддерживаемых языков (C++, C#, Basic - всё равно) в свой IL-код, а уж потом выходит бинарник. Так по сути - какая разница на каком языке, если есть ещё общий для всех IL?
Или моя логика неверна? Было бы интересно знать.
bool, посмотри курс по C/C++ на intuit.ru. Там вроде не особо сложно.
Coutty
Студия умеет генерить для C++ как нэйтив код, так и IL. Драйверы всё ещё в нэйтив делают. К тому же в плюсах работа с указателями много прозрачней, чем в C# (в котором указатели тоже есть, но более ограниченные. Основное назначение - связка с ансэйф кодом; непосредственно при программировании ими никто не пользуется).
Diseased Head
18-11-2006, 19:43
Coutty ты чёт... Так по сути - какая разница на каком языке, если есть ещё общий для всех IL? Так именно поэтому и системные проги писать не катит. Потому как все в IL-код, а уж как он потом это в машкод переделывает (???).
Я так думаю, может я не прав. Я в C# не силён.
bool, стандартные шаги:
1. напиши прогу "hello, world" (ещё один сишник родился)
2. программу поиска максимального и минимального элемента массива
3. определитель матрицы
4. изменяемый список (рекомендуется двухсвязный)
5. быстрая сортировка этого списка.
Думаю на этом этапе желание работать с чистым C пропадёт
забыл совсем про эту тему , да и времени не хватало. Вот по поиску максимального и минимального элемента, что то сразу застопорился)
массив задаю с 11 элементами, а почему позволяет вводить только 5 и сразу результат, и только на максимальный. Ещё подскажите как нужно правильно в начале объявить функции которые будут возвращать значение int, и в которую я буду передавать как аргумент - массив.
#include <stdio.h>
char find_max(char *x);
char find_min(char *n);
main(void)
{
int t;
char a[10];
printf("input elements of array\n");
for(t=0;t<10;t++){
scanf("%c",&a[t]);
}
printf("Max = %c\n",find_max(a));
printf("Min = %c",find_min(a));
}
char find_max(char *x)
{
int t;
char max;
max=x[0];
for(t=1;t<10;t++){
if(x[t]>max) max=x[t];
}
return max;
}
char find_min(char *n)
{
int t;
char min;
min=n[0];
for(t=1;t<10;t++){
if(n[t]<min) min=n[t];
}
return min;
}
чет меня заклинило 8) пардон, вот работает) посмотрите пожалуйста , как можно оптимальнее её написать, и ещё такой вопрос: вот допустим я хочу прям в программе ввести величину массива. Мне нужно сначала объявить переменную int size; /* размер массива */
а как потом объявлять сам массив? так ведь нельзя: int a[size] , потому что переменная size ещё не определена. Подскажите пожалуйста.
#include <stdio.h>
find_max(int *x);
find_min(int *n);
main(void)
{
int t;
int a[10];
printf("input elements of array\n");
for(t=0;t<11;t++){
scanf("%d",&a[t]);
}
printf("Max = %d\n",find_max(a));
printf("Min = %d",find_min(a));
}
find_max(int *x)
{
int t;
int max;
max=x[0];
for(t=1;t<11;t++){
if(x[t]>max) max=x[t];
}
return max;
}
find_min(int *n)
{
int t;
int min;
min=n[0];
for(t=1;t<11;t++){
if(n[t]<min) min=n[t];
}
return min;
}
массив переменного размера, так называемый динамический берётся из свободной памяти:
int size1 = 10;
int* array1 = new int[size1];
...
delete[] array1;
усовершенствовать алгоритм поиска мин/макс дальше сложно. Можно только сделать его более универсальным, не теряя производительности:
// возвращает указатель на минимальный элемент или на конец массива (если он пустой)
int* find_min(int* first, int* last)
{
int* result = first;
if (first!=last)
{
while(++first!=last) if (*first<*result) result=first;
}
return result;
}
...
// вообще бы надо проверить, что size1>0
int* min1 = find_min(array1, array1+size1);
print("found minimum %d at position %d\n", *min1, ((unsigned)min1-(unsigned)array1)/sizeof(int));
// минимум среди первых 10:
int* min1 = find_min(array1, array1+min(size1,10));
print("found minimum %d at position %d\n", *min1, ((unsigned)min1-(unsigned)array1)/sizeof(int));
bool
а как потом объявлять сам массив? так ведь нельзя: int a[size] , потому что переменная size ещё не определена. Подскажите пожалуйста.В C99 так можно.
В дополнение к ответу pva - если массив состоит из данных POD-типа (http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html), имеет небольшой размер и его время жизни привязано к области видимости функции (т.к. по выходу из функции он должен быть убит), то можно воспользоваться функцией alloca. Так сказать, pure-C way.
а турбо С поддерживает С99? у меня почему то ошибку в синтаксисе показывает, может удобнее учиться на чем нибудь другом? что посоветуете? борланд 6 ?
если уж билдер 6, то это достаточно продвинутый компилятор, чтобы использовать шаблоны с++. Есть например такой: vector<typename T>
#include <vector>
#include <fstream>
using namespace std;
void myFunc()
{
vector<double> fdoubles(100, 0.);
// создан объект std::vector<double>,
// представляющий собой обычный массив из 100 элементов
// и инициализирован значением 0.0
// объект будет уничтожен автоматически при выходе из блока
// для работы с памятью используется класс std::allocator<double>.
// тот, который по умолчанию использует операторы new и delete[],
// но можно их переопределить (но лучше не трогать, если нет острой необходимости)
// работаем как с обычным массивом:
fdoubles[0] = 3.14;
fdoubles[1] = 123.23;
// если нужна проверка границ:
fdoubles.at(0) = 3.14;
fdoubles.at(101) = 123.23; // здесь вылетит с исключением std::out_of_range
// меняем размер, если надо, память перераспределяется автоматически
// но так, что если просишь меньше, то не освобождается, а просто берётся меньше
// из уже выделенного куска. Например:
fdoubles.resize(50); // используется кусок из 100*sizeof(double)
fdoubles.resize(200); // используется кусок из 200*sizeof(double)
}
vector<double> readData()
{
// работа с памятью оптимизирована для добавления небольших объектов.
// то есть это идеальный класс для использования в качестве буфера чтения (небольших объектов)
// и использования индексации.
ifstream input("my_data.txt");
double buf;
vector<double> result;
while(input>>buf) result.push_back(buf);
return result;
}
// TList в делфи - это аналог vector<void*>
pva
спасибо, но я попытаюсь освоить сначала всю функциональность С =) без С++.
Пишу программку определения определителя матрицы и у меня такой вопрос возник: правильно ли будет объявлять в цикле главной функции массив? Ведь при каждой итерации цикла будет создаваться новый массив, или он будет заменяться старым?
допустим вот такая ситуация:
pm=--pm; /* pm изначально определена, например pm=5 */
for(бла бла бла) {
бла бла бла
int f[pm][pm]; /* вот здесь =) */
бла бла
}
или лучше в цикл включить функцию объявленную заранее в которой будет этот массив объявляться и по её завершению удаляться, а потом при след. итеррации создаваться вновь?
что то я затормозился на этом определителе. использую рекурсивную функцию для определения.
finder(int *a)
{ register int k;
int answer;
if(a[k][k])
if(k==2) answer = a[k-1][k-1]* a[k][k]-a[k-1][k] * a[k][k-1];
answer = (-1)^(k+1) * a[1][k] * finder(a[k-1][k-1]);
return(answer);
}
в функцию передается указатель на массив, но как передать переменную - порядок матрицы? т.е. то чем в функции подменяется переменная к? в моем случае получается, что я её использую до определения
все остальное:
#include <stdio.h>
#define n 5
finder(int *a);
void main(void)
{
int b[n][n];
int pm = 5;
int opr=0;
int opr1=0;
int s;
for(s=1;s<n;s++){
pm = pm--;
int p[pm][pm]; /*здесь опять ошибка синтаксиса С89 */
opr=(-1)^(s+1) * b[1][s] * finder(p);
opr1=opr1+opr;
}
}
подскажите пжлст =)
если действовать рекурсивно, то надо каждый раз делать копии подматриц (потому что по сути при выбрасывании столбца и строки метрица меняется). Но можно выбрасывать только индексы.
// приучайте мышление к универсальным алгоритмам - шаг к С++
typedef int value_type;
typedef unsigned size_type;
value_type internal_det(value_type const** rows, size_type* cols, size_type size)
{
value_type result;
// rows - это указатели на строчки (с пропусками)
// cols - индексы столбцов (тоже с пропусками)
// чтобы взять элемент i, j такой матрицы, нужно:
// elem = rows[i][cols[j]];
if (2<size)
{
size_type size_less = size-1;
value_type** rows_less = new value_type*[size_less];
size_type* cols_less = new size_type[size_less];
// собираем матрицу с выброшенным первым столбцом (и строчкой):
for(size_type i=1; i<size; ++i) rows_less[i-1] = rows[i];
for(size_type j=1; j<size; ++j) cols_less[j-1] = cols[j];
// собираем поочереди:
for(size_type i=0; i<size_less; ++i, rows_less[i]=rows[i]) {
for(size_type j=0; j<size_less; ++j, cols_less[i]=cols[i]) {
// я точно не помню формулу, но суть в следующем:
// получаем определитель матрицы с выброшенным элементом
value_type det1 = internal_det(rows_less, cols_less, size_less);
...
}
}
delete [] cols_less;
delete [] rows_less;
}
else
{
// матрица 2x2
result = rows[0][cols[0]] + rows[1][cols[1]] - rows[0][cols[1]] - rows[1][cols[0]];
}
return result;
}
value_type det(value_type* matrix, size_type n)
{
value_type** rows = new value_type*[n];
size_type* cols = new size_type[n];
for(size_type i=0; i<n; ++i) rows[i] = matrix + n*i;
for(size_type i=0; i<n; ++i) cols[i] = i;
return internal_det(rows, cols, n);
}
ferrum2688
05-03-2007, 10:56
Нужны задания?
Напиши марио, змейку, в общем какую-нибудь простенькую игру.
pva
огромное thx 8) сейчас переварю это (с новыми типами) допишу с формулой и перейду к структурам =)
ferrum2688
на С? я до такого уровня ещё не дошел, чтобы игры на нем писать, я даже не представляю как графический интерфейс на С стряпать ))
ferrum2688
06-03-2007, 15:32
на С? я до такого уровня ещё не дошел, чтобы игры на нем писать, я даже не представляю как графический интерфейс на С стряпать ))
На C,C++ можно просто использовать текстовый режим, члены змейки можно сделать например "*". Конечно в графическом лучше, потому что символы имеют разную высоту и ширину.
В принципе достаточно только gotoxy(int x,int y) и cprintf("*"); , для очистки cprintf(" "), думаю этого достаточно для графики, есть конечно ещё и др. функции(clrscr();-очистка всего экрана), но написать можно и без них. Для того чтоб понять программирование можно писать с ограниченным числом функций, нужно подумать возможно ли на основании твоих знаний решить данную задачу, а большинство придуманных функций для ускорения процесса создания и можно обойтись без них. Например возведение в степень(целую), извлечение корней(целых) можно сделать из:+,-,*,for,if.
// приучайте мышление к универсальным алгоритмам - шаг к С++
typedef int value_type;
typedef unsigned size_type;
я уже понял почему на чистом Си писать неудобно) тот же typedef помоему взят уже из С++, по крайней мере его использовать, помоему , можно только в Вин компиляторах(вычитал у Г.Шилдта =) и мой турбо Си отказывается запускать и ругается на синтаксис при его применении) , но все же хочу опробывать все функции которые Шилдт описывает в своем издании, и потом уже начинать освоение С++ (там так и указано в самом начале справочника по С++ "перед началом изучения С++ вы должны знать основы С" ).
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.