Четверг, 28 Марта 2024, 20:22

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Программирование » C/C++ » Уроки по программированию по си и c++
Уроки по программированию по си и c++
afqДата: Среда, 12 Июня 2019, 06:28 | Сообщение # 1
Разработчик
Сейчас нет на сайте
Решил сделать уроки по си и c++. Правда не знаю, получится ли делать годный материал. Первое видео какое записал на эту тему, не разработка программы, а

Приведение типов в си.


То есть я даже и не думал раньше что так можно.
Код

((struct b*) &a)->b

То есть код такое будет работать.
Код

#include <stdio.h>

struct a {
        char a[4];
}a;
struct b {
        int b;
};

int main ( )
{
        char *m = &a.a[0];
        for ( int i = 0; i < 4; i++, m++ ) *m = 0;
        a.a[0] = 3;
        printf ( "%d\n", ((struct b*) &a)->b );
}

Я это заметил случайно, когда додумался до этого, типа а что если так попробывать. И действительно получилось, и тогда моё понимание к си приблизилось. Даже не знаю, хорошо ли я объясняю. Нужен ли такой материал?

Добавлено (12 Июня 2019, 06:29)
---------------------------------------------
Об этом я узнал где-то год или два назад. Хотя писал на си уже где-то два года, но редко.

Добавлено (12 Июня 2019, 06:30)
---------------------------------------------
Видео получилось почему то низкого качества, щас посмотрю.

Добавлено (12 Июня 2019, 06:50)
---------------------------------------------
Офигеть, я так объясняю хахаха. Ещё такая речь. Блин. prof

Добавлено (12 Июня 2019, 07:34)
---------------------------------------------
Не нафиг надо. Видео получилось ужасным.

Добавлено (12 Июня 2019, 07:34)
---------------------------------------------
Врядли я буду обучать программированию.

Сообщение отредактировал afq - Среда, 12 Июня 2019, 06:37
TLTДата: Пятница, 14 Июня 2019, 12:24 | Сообщение # 2
Сейчас нет на сайте
Цитата afq ()
Видео получилось ужасным.


Можно часть с ужасного... и прогрессировать постепенно. Всё сразу даётся на высоком уровне.


Дао, выраженное словами, не есть истинное Дао.
coremissionДата: Понедельник, 17 Июня 2019, 19:19 | Сообщение # 3
частый гость
Сейчас нет на сайте
не надо делать уроки по с++, когда вы в нем не разбираетесь.
Хорошие уроки есть УЖЕ на stepik.org например. бесплатные, без смс и точно очень хорошие.
XakepДата: Вторник, 18 Июня 2019, 05:14 | Сообщение # 4
めちゃくちゃちゃ
Сейчас нет на сайте
Цитата afq ()
То есть я даже и не думал раньше что так можно.

Ну тут нет никакой магии, только костыли :) не стоит так никогда делать. Ну и выше верно подметили, не стоит делать уроки по C/C++, особенно для новичков, лучше показывать как можно решать определенного рода интересные задачи на том же C/C++
afqДата: Вторник, 18 Июня 2019, 06:26 | Сообщение # 5
Разработчик
Сейчас нет на сайте
Цитата
Ну тут нет никакой магии, только костыли :) не стоит так никогда делать.

Xakep, как это не стоит. Это очень удобно, и это не костыль. Ситуации бывают разные. Именно поэтому я с тобой не соглашусь. Смотри пример.
Код

#include <stdio.h>
#include <stdlib.h>

struct head {
    int number;
};

struct data {
    char d[255];
};

struct auth {
    char login[32];
    char password[32];
};
static void fill ( char *data )
{
    data[0] = (char) 1;
}
#define AUTH 1
#define DATA 2
struct data *data;
struct auth *auth;
int main ( )
{
    char *buffer = calloc ( 255, 1 );
    fill ( buffer );

    switch ( ( ( struct head * ) buffer )->number ) {
  case AUTH:
   auth = ( struct auth * ) &buffer[0];
   return 0;
  case DATA:
   data = ( struct data * ) &buffer[0];
   return 0;
    }
}

Это гораздо удобнее, чем делать так.
Код

    struct head *head = ( struct head * ) &buffer[0];
    int number = head->number;
    switch ( number ) {

И с чего это вдруг твои советы должны быть правильными? С чего ты вообще взял что приводить к типу не стоит?
XakepДата: Вторник, 18 Июня 2019, 09:53 | Сообщение # 6
めちゃくちゃちゃ
Сейчас нет на сайте
И что это за пример? ничего не понятно, какую проблему ты решаешь?

Цитата afq ()
С чего ты вообще взял что приводить к типу не стоит?

А я и не говорил что приводить к типу не стоит, другое дело, что у тебя переменные совершенно разных типов и имеют разные данные, подобный код скрывает в себе Undefined Behavior, при этом запутывает читателя. Ты пытаешься сделать какое-то подобие полиморфизма, если так хочется - делай по нормальному - возми тот же C++ и опиши интерфейс и для 2х типов уже реализуй этот интерфейс.

Добавлено (18 Июня 2019, 10:02)
---------------------------------------------
Кстати второй пример отличается от первого, в первом примере у тебя адрес памяти на структуру a, которую ты преобразуешь в структуру b. В твоем примере у обоих типов одинаковый размер, меняшь у одного типа размер, преобразуешь в другой тип, пытаешься прочитать член, для которого не выделено памяти и получаешь либо Segmentation Fault, либо, что еще хужеб UB - в каких-то случаешь все будет отрабатывать, либо отрабатывать криво косо, в других падать.

Сообщение отредактировал Xakep - Вторник, 18 Июня 2019, 09:59
afqДата: Вторник, 18 Июня 2019, 10:08 | Сообщение # 7
Разработчик
Сейчас нет на сайте
Xakep, но это я из си узнал. Вот ещё пример, это уже из сетевого программирования.
Код

        struct sockaddr client;
        socklen_t len = sizeof ( struct sockaddr );
        accept ( sock, &client, &len );
        int port = htons ( ( ( struct sockaddr_in * ) client )->sin_port );

Так можно узнать какой порт у клиента, приведя его к структуре sockaddr_in. Но проще в этот случае сразу использовать sockaddr_in.
Код

        struct sockaddr_in client;
        socklen_t len = sizeof ( struct sockaddr_in );
        accept ( sock,(struct sockaddr *) &client, &len );
        int port = htons ( client->sin_port );

Просто структуру sockaddr обычно требуют функции для сетевого программирования,а для удобства использования данные есть структура sockaddr_in, которая уже имеет нужные данные из sockaddr. Эти единственные структуры, что я знаю, которые делают такие вот выкрутасы с данными.
drcrackДата: Вторник, 18 Июня 2019, 10:15 | Сообщение # 8
старожил
Сейчас нет на сайте
https://habr.com/ru/post/143072/
afq, не хочешь поучаствовать?

PS
Си в естественной среде обитания:
Код

#include <stdio.h>

char E[1<<25]="              ; } }     { { } { { ; ; {     } } { { ;   { { {       { { } ; }   { { ; {   { { ;     { } ; ; ; {     ; ; ; }   } ;   } { { ;   } }   ; } } ; ; }     { ; } } { } } }       } }   ; { { } } } ;   } } } {   }   ; ; ; {     } ; { { {   ; {   ; } } {   { { } { { ; ; { {   } } { { ;   { { {       { { } ; }   { { ; {   { { ;     { } ; ; ;       ; ;   }   } ;   } { { ;   } }   ;   } ; ; }     { ; }   } } } }       } }   ; { { }   ; ;   }   ; {   }   ; ; ; {     } ; {   {   ; {   ; } } {   { { } {   ; ; { {   } } { {   { { { {       { {     ;   {   ; {   {   ;     {         {     ; ;     { } ;     ",
*a[40],*q=E+20,*T=E+1080;
int i=1,j,k,l,u,w,I,J,K,h,H,G,R=4,U,e[999],*p=e+5,*r,*s,*v,b[999],L[1<<16],
F=882,n[99];
FILE*f;

#define Y(a,b) (a)<(b)?(a):(b)
#define Z(a,b) (a)>(b)?(a):(b)
#define X(x,a,b)Z(a,Y(b,x))
#define O      [s]
#define N      [v]
#define M      [r]
#define C      ++
#define m      :0
#define g      m,
#define d      u==
#define z(o)   32 O?n[X(32 O+o+(35 O-24)/256,0,59)]m
#define y(o)   32 O?8 O=z(o)m
#define x      (p=e+5*34 O,2 M-3 && 2 M-5?y(0),l=p[4],a[i]=a[8+34 O],3 N=l>1?\
               2*(p[3]+l):2*p[0],4 N=l>1?2*l:1,0 N=Y(2 M-9?0:9 O<<8,3 N-1) m)
#define W(t,i) (u=t[i]>>4,w=t[i]&15),
#define Q(e)   ((1 N+=13200)>=5 N?1 N-=5 N, C 0 N>=3 N?0 N-=4 N m g e*6 N*q[0\
               N]/34)+
#define D(b,i) T[i]==*#b&&T[i+2]==#b[1]
#define A      ((unsigned char*)q)
#define V      *p C=
#define S(a)   V(A[a]<<8)|A[a+1],
#define P      2 M==
#define B      ,putchar
#define o      for(

int main(int t,char**c)
{
    o; w=E[u]; C u)n[u/10]+=(w-59?w-125?w-32?1 m:2:3)<<u%10;
    o t=fread(E,i,1<<24,f=fopen(c[i],"rb")),
        t=D(FT,0)?R=T[3]-48,32:D(CN,1)?R=*T-48,32:D(MK,0)?32:16;
        i C<t;
        S(0)V(A[2]&7)-2*(A[2]&8),V A[3],S(4)S(6)q+=8) q+=22;
    o H=*A,T=q+=2,q+=t>15?132:128;
        k<128;
        k C) G=X(G,T[k]+1,128);
    o p=L; j C<R*64*G; q+=4)
        o W(A,2)V*A&240|u,V i=0,V w,V A[3],k=((*A&15)<<8)|A[1],l=9<<19;
            k&&i C<60;
            u=k-n[i],u*u<l?p[-3]=i,l=u*u:l);
    o i=1; i<t; a[8+i]=q,q+=2*e[5*i C]);
    o t=6; !U; ) {
        o i=0; i<R;
            v=b+7*i,r=L+4*(R*(64*T[K]+J)+i),s=e+200+50*i,j=3 M&15,
            I?
                W(s,2 M)P 5||P 6||P 10?0 O =u?Y(0 O+u,64):Z(0 O-w,0) g
                P 0?W(r,3)(u|w)?y((I%3-1?I%3-2?0:w:u)) m g
                8 O=P 1?Z(113,8 O-1 O):P 2?Y(856,8 O+2 O):8 O,
                P 5||P 3?l=z(0),8 O>l?8 O=Z(8 O-3 O,l):8 O<l?Y(8 O+3 O,l) m g
                U|=P 11&&I==t-1,
                P 13&&I==t-1?W(r,3)K C,J=10*u+w-1 g
                P 14?
                    W(r,3)
                     d 6?j?I==t-1?38 O=38 O<j?J=37 O-1,38 O+1 m m:(37 O=J) g
                     d 9&&C 39 O==25 O?39 O=0,x g
                     d 12&&I==28 O?0 O=0 g
                     d 13&&I==e[29]?x m
                     m
            :(
                0 M?34 O=0 M,p=e+5*34 O,35 O=p[1],0 O=p[2] g
                3 M?2 M O=3 M g
                1 M&&(2 M-14||((3 M>>4)-13))?32 O=1 M,x g
                0 O=P 12?X(3 M,0,64) m O ,
                P 15?(l=3 M)?l<33?t=l:(F=110250/l) m g
                P 14?
                    W(r,3)
                    j?(16+u) O=j g
                    8 O=d 1?Z(113,8 O-17 O):d 2?Y(856,8 O+18 O):8 O,
                    d 5?35 O=(j&7)-2*(j&8) g
                    d 9?39 O=25 O&&!1 M?x,0 m g
                    0 O=d 10?Y(0 O+26 O,64):d 11?Z(0 O-27 O,0):0 O,
                    d 14?h=30 O m m),
            6 N =X(0 O,0,64),
            5 N =999*8 O,
            i C);
        o C I>=t+t*h?I=h=0,C J>=64?J=0,U|=C K>=H m g j=F; j--; 0
            B(u)B(u>>8)B(w)B(w>>8))
            o i=u=w=0; i<R;
                v=b+7*i,q=a[i C],q?l=Q(1)Q(4)Q(12)Q(12)Q(4)Q(1)0,
                  k=1<<(i&2),u+=l/k,w+=l/(k^5) m);
    }
    return 0;
}


Сообщение отредактировал drcrack - Вторник, 18 Июня 2019, 10:16
XakepДата: Вторник, 18 Июня 2019, 10:26 | Сообщение # 9
めちゃくちゃちゃ
Сейчас нет на сайте
Вангую что т.к. это работа с сетью, то структуры должны иметь строгую схему, к примеру - сначала адрес приемника, потом адрес отправителя, сообщение итд. Скорее всего это просто устаявшийся способ использования конкретно этих структур, плюс функция accept принимает len, что намекает на то, что функция не будет пытаться вылазить за пределы данных структуры sockaddr_in. Это конечно все догадки. И для меня такой код считается не самым лучшим - сетевое это программирование или нет, не важно.
Один из вариантов, как это можно было-бы сделать более читабельнее и понятнее:

Код

void sockaddr_in_accept(? sock, struct sockaddr_in* client) { // не в курсе какой там тип нужен для sock
    socklen_t len = sizeof(struct sockaddr_in);
    accept(sock, (struct sockaddr*) &client, &len);
}

void some_action() {
    struct sockaddr_in client;
    sockaddr_in_accept(sock, &client);
    int port = htons(client.sin_port);
}


Собственно вроде как бы код делает тоже самое, но страшную идиому мы прячем под sockaddr_in_accept, и спокойно пользуемся типом sockaddr_in.


Сообщение отредактировал Xakep - Вторник, 18 Июня 2019, 12:43
Форум игроделов » Программирование » C/C++ » Уроки по программированию по си и c++
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг