Any C programmers wanna help convert code to convert between MIDI + CSV?
#21
(08-26-2022, 09:37 PM)mnrvovrfc Wrote:
(08-26-2022, 08:36 PM)TempodiBasic Wrote:  never seen this way to assign a value to a string variable  in C
  buf[p][0]="CDEFGAB"[(n+700000)%7];
That is a syntax error in C, perhaps not in C++. I've seen stranger things happen with C++ code, perhaps square-bracket operators were overloaded? Otherwise the intention of the programmer looks like one of the letters is being extracted.

Just doing buf[p][0]="CDEFGAB"; might not be allowed in C, must allocate memory for pointer for string "array", then more memory for each member of the array and then use "strcpy()" or something like that from "string.h". This is just my near-fundamental knowledge of that programming language...

You got it.  In C, string literals are one dimensional arrays of characters and can be treated as such.
The square brackets are an index into that array, allowing access to one character at a time.

It's not a kind thing to do to human source code reviewers, but it works.
Tricks like this are why C is often called a "write only" language.  It can be playful fun writing C code like the above, but good luck understanding that source code later.

These two programs, the first in C and the second in Basic, print the same output, one character at a time:
Code: (Select All)
#include <stdio.h>

int main(void) {
int i=0;
char c;
    for (i=0; i<6; ++i) {
        c = "ABCDEF"[i];
        putchar(c);
    }
    return 0;
}

Code: (Select All)
for i=1 to 6
    c$ = mid$("ABCDEF",i,1)
    print c$;
next
Reply
#22
@JRace

Thanks... it seems to me too dirty and not a straight C code!
a string is an array of chars both in C both in Pascal.
but this let me remember why I have more a theoretical than  practical knowledge of it...
all these tricks that seem exceptions to the main rule, all possible but with no regard to clarity,
if you find and study them you can understand, otherwise you are in a nightmare... no logic and no syntax can help you.

char s;
s = "ABCD"[1];
printf (%c,s);

and

char s;
s = 'A';
printf (%c, s);


they do the same thing.

.... there are other deprecated ways about coding style like the use of Asset to control bounds range of variables and sprintf  with int variables and so on.

I have some trouble to  understand  what the author was doing and why... so the translation will be only literal, I have no chances to write a good code in QB64 that does the same thing in a more manner of QB64.

There will be another path to reach the goal to manage MIDI files...
Reply
#23
(08-27-2022, 11:22 PM)TempodiBasic Wrote: @JRace

Thanks... it seems to me too dirty and not a straight C code!
a string is an array of chars both in C both in Pascal.
but this let me remember why I have more a theoretical than  practical knowledge of it...
all these tricks that seem exceptions to the main rule, all possible but with no regard to clarity,
if you find and study them you can understand, otherwise you are in a nightmare... no logic and no syntax can help you.

char s;
s = "ABCD"[1];
printf (%c,s);

and

char s;
s = 'A';
printf (%c, s);


they do the same thing.

.... there are other deprecated ways about coding style like the use of Asset to control bounds range of variables and sprintf  with int variables and so on.

I have some trouble to  understand  what the author was doing and why... so the translation will be only literal, I have no chances to write a good code in QB64 that does the same thing in a more manner of QB64.

There will be another path to reach the goal to manage MIDI files...

This is why I was asking how to use QB64's C compiler - so we can take weird lines of code like this, and run them in a test, to see exactly what they do. 

Also, the code sort of works. I think if we break it down, the number of the weirder statements isn't so much. 

And for the ASSERT, if those are defining out-of-bounds values, you merely check for those whenever the variable in question changes with IF/THEN statements. 

At least that's how I would approach it...
Reply
#24
Pascal was designed for clarity, so there is sometimes only one way of making your program logic work.  Basic is a Swiss Army Knife; it's not always the most efficient tool for the job, but it is compact and versatile and will get the job done.  C gives you a metric boatload of choices for building small, fast-running programs, even with a simple, non-optimizing compiler.  Of course you don't need to use every C trick in the book, just the ones you feel comfortable with.

Trying to figure out someone else's C code can make you feel dizzy, especially if they wrote the source code for their own eyes, without considering whether other people could understand it.

Hence the old joke that Pascal is a Read-Only language, and C is a Write-Only language.

As I was learning C, experimenting with things like the ternary conditional operator (? ... :...), I discovered just how easy it is to make an unreadable, unmaintainable mess (see https://en.wikipedia.org/wiki/Internatio...de_Contest for examples, all done just for fun!).  You can nest ternaries within ternaries, etc, which all feels clever & fun until you have to find deeply nested bugs.




@madscijr :
Quote:Also, the code sort of works. I think if we break it down, the number of the weirder statements isn't so much.

That's how I would attack it.  Personally, I'd convert EVERY line of C code to a Basic comment, then start opening it up, adding spaces and blank lines, dividing it into blocks and figuring out what each block does, and what each line within each block does.  Documenting everything with comments.  You can use the original C as a pseudocode and create the Basic program in between lines & blocks of C code.  Literal translation is possible, but as you decipher each section of code, it MAY actually be easier to rewrite from scratch in Basic.

Also, if you go back to your earlier thread "hacking into the c compiler?", I edited my reply (https://staging.qb64phoenix.com/showthre...52#pid5752) on the next day, clarifying a few things and improving that included batch file to clarify its operation.
Reply
#25
(08-27-2022, 11:22 PM)TempodiBasic Wrote: :
char s;
s = "ABCD"[1];
printf (%c,s);

and

char s;
s = 'A';
printf (%c, s);


they do the same thing.
:
The "printf()" line should be:
Code: (Select All)
printf("%c", s);
This is in case you or somebody else is learning how to program in C, to clear up confusion. "printf()" expects at least one parameter which is the format, which is a pointer to a variable of type "char". It could be a string literal in double-quotation marks in this case.

Otherwise you could have seen what @JRace did in an earlier post and used instead:
Code: (Select All)
putchar(s);
Reply
#26
@mnrvovrfc
right feedback, I miss to type double <"> for printf format
and yes I can use also putchar(s); an elder function of C
Reply
#27
Quote:Personally, I'd convert EVERY line of C code to a Basic comment, then start opening it up, adding spaces and blank lines, dividing it into blocks and figuring out what each block does, and what each line within each block does.
Lol, it spends a lot of time!
Reply
#28
Quote:JRace - You got it.  In C, string literals are one dimensional arrays of characters and can be treated as such.
The square brackets are an index into that array, allowing access to one character at a time.


You can also create multidimensional arrays. In memory they are also stored as an order, but they can be accessed only by row and column specs.

The following example creates a two-dimensional magic square. By specifying row + column, you can specifically access the individual field elements; number <space> number. A field in C starts at zero.
Incorrect entries are not intercepted!

The editor has some problems with a C source text. Well, the competition!  Rolleyes
Code: (Select All)
//Zugriff auf Feldelemente - 29. Aug. 2022

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

int main(void)
{
    int magisches_quadrat[4][4] = {
                                                                    {16, 3, 2, 13},
                                                                    {5, 10, 11, 8},
                                                                    {9, 6, 7, 12},
                                                                    {4, 15, 14, 1}
                                                                };
    int feldelement1, feldelement2, *zgr;
    int *zgr_mag = &magisches_quadrat[0][0];
        
    printf("\nZugriff auf zweidimensionales Feld\n");
                
    //Quadrat ausgeben
    printf("\nMagisches Quadrat ausgeben:\n");
    
    for(int i = 0, j = 1; i < 16; i++, j++)
    {
        printf("%2d ", zgr_mag[i]);
        if(j % 4 == 0)
            printf("\n");
    }
    //Zeile, Spalte beginnt in C bei 0!
    printf("\nInhalt von [2][3] = %d", magisches_quadrat[2][3]);
    
    printf("\n\nWelches Feldelement soll angezeigt werden?");
    printf("\nGeben Sie das Element an[][] - Zahl <> Zahl: ");
    scanf("%d %d", &feldelement1, &feldelement2);
    
    printf("\nInhalt von [%2d][%2d] = %2d", feldelement1, feldelement2,
                                                                                magisches_quadrat[feldelement1][feldelement2]);
    
    printf("\n\n");
    return(0);
}

Example:
[Image: Zugriff-auf-Feldelemente2022-08-29.jpg]
Reply
#29
(08-29-2022, 12:18 AM)TempodiBasic Wrote:
Quote:Personally, I'd convert EVERY line of C code to a Basic comment, then start opening it up, adding spaces and blank lines, dividing it into blocks and figuring out what each block does, and what each line within each block does.
Lol, it spends a lot of time!

It is methodical.  It is useful if you are going in cold, with no idea how the original program works.  How long it takes depends on the complexity of the original source.  If the source is organized into sections or blocks which can be isolated, then as you figure out how each section works you can rewrite that section or block in Basic.

I'm doing this to one of my old programs, translating from Lua to Basic.  Rather than rewrite from scratch and go through all the debugging and fine tuning needed, I'm just translating and improving my old program.  I'm not under any productivity quotas, so there is no hurry.

Now that I've done the interesting part of solving the major problems, I just need to motivate myself to do the tedious part and finish the job.   Sad
Reply
#30
(08-29-2022, 01:25 PM)Kernelpanic Wrote:
Quote:JRace - You got it.  In C, string literals are one dimensional arrays of characters and can be treated as such.
The square brackets are an index into that array, allowing access to one character at a time.


You can also create multidimensional arrays. In memory they are also stored as an order, but they can be accessed only by row and column specs.

The following example creates a two-dimensional magic square. By specifying row + column, you can specifically access the individual field elements; number <space> number. A field in C starts at zero.
Incorrect entries are not intercepted!

The editor has some problems with a C source text. Well, the competition!  Rolleyes
Code: (Select All)
//Zugriff auf Feldelemente - 29. Aug. 2022

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

int main(void)
{
    int magisches_quadrat[4][4] = {
                                                                    {16, 3, 2, 13},
                                                                    {5, 10, 11, 8},
                                                                    {9, 6, 7, 12},
                                                                    {4, 15, 14, 1}
                                                                };
    int feldelement1, feldelement2, *zgr;
    int *zgr_mag = &magisches_quadrat[0][0];
        
    printf("\nZugriff auf zweidimensionales Feld\n");
                
    //Quadrat ausgeben
    printf("\nMagisches Quadrat ausgeben:\n");
    
    for(int i = 0, j = 1; i < 16; i++, j++)
    {
        printf("%2d ", zgr_mag[i]);
        if(j % 4 == 0)
            printf("\n");
    }
    //Zeile, Spalte beginnt in C bei 0!
    printf("\nInhalt von [2][3] = %d", magisches_quadrat[2][3]);
    
    printf("\n\nWelches Feldelement soll angezeigt werden?");
    printf("\nGeben Sie das Element an[][] - Zahl <> Zahl: ");
    scanf("%d %d", &feldelement1, &feldelement2);
    
    printf("\nInhalt von [%2d][%2d] = %2d", feldelement1, feldelement2,
                                                                                magisches_quadrat[feldelement1][feldelement2]);
    
    printf("\n\n");
    return(0);
}

Example:
[Image: Zugriff-auf-Feldelemente2022-08-29.jpg]

Oh yeah, you can create multidimensional arrays in C, but a string literal such as "Hello, world!" is treated as a one dimensional array of characters, with a NULL (0) as the last element.

If you try to create a multidimensional string array in C, you are really only creating an array of pointers to strings.
Reply




Users browsing this thread: 14 Guest(s)