Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Please Help me.

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Please Help me.
Doctor Cop
Member #16,833
April 2018
avatar

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

int main() {

char name[100], ch;
int i = 0, cout[10]={0};

gets(name);

for(int j=0; j<strlen(name); j++)
{
if(name[j] < '9' && name[j] > '0')
cout[atoi(name[j])]++;
}

for(int l=0; l<10; l++)
printf("%d ",cout[l]);
return 0;
}

This program returns segmentation errors.
please help!

amarillion
Member #940
January 2001
avatar

You're attempting to pass a single char to atoi. But atoi takes a const char *. It seems to me that this is causing the crash.

A better way to convert a char to a numeric value is to simply substract the ascii code of '0', something like:

int idx = (int)(name[j] - '0')

Where you write

if(name[j] < '9' && name[j] > '0')

You probably mean

if(name[j] <= '9' && name[j] >= '0')

If I may say so, your code is very messy, and there are a number of things you could improve.

When posting code in the forums, use < code > tags to format the code.

Why is the variable called 'name' when it takes a string of digits? What is the intention of the variable named 'cout'? Better variable naming is the first step to better code and fewer bugs.

There is a variable 'ch' that is unused. Code hygiene is the second step to better code.

You are often trying to do a lot of operations on a single line. This is not helpful if you're a beginner and you're trying to understand the way code works. Therefore I would write out a line like

cout[atoi(name[j])]++; 

in multiple steps, until you know what you're doing. It will also help to print intermediate values in your calculation and check that they are correct.

Also, you're calling strlen in a loop, which has O(N^2) complexity

Doctor Cop
Member #16,833
April 2018
avatar

#SelectExpand
1#include <stdio.h> 2#include <string.h> 3#include <math.h> 4#include <stdlib.h> 5 6int main() { 7 8 char string[1000]; 9 int i = 0, count[10]={0}; 10 11 gets(string); 12 13 for(int j=0; j<strlen(string); j++) 14 { 15 if(string[j] <= '9' && string[j] >= '0') 16 count[(int)(string[j]-'0')]++; 17 } 18 19 for(int l=0; l<10; l++) 20 printf("%d ",count[l]); 21 return 0; 22}

Thanks man, my code runs now.
I made changes according to you but what was with that O^2 thing.
I don't know, I am a beginner please tell me.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

He was using Big O Notation. O(n^2) means the complexity of your code is n^2.

A for loop like this :
for (int i = 0 ; i < function() ; ++i) {/*...Loop body...*/} will execute loop body until (i < function()) returns false. function() is being called on every iteration of the loop. strlen is O(n) and you're calling it n times so the complexity is O(n*n) = O(n^2).

Move the strlen call in front of the for loop. It only needs to be calculated once.

https://upload.wikimedia.org/wikipedia/commons/7/7e/Comparison_computational_complexity.svg

Doctor Cop
Member #16,833
April 2018
avatar

Edgar Reynaldo: Thanks man, you people are really good.
I like this form, with your help I am becoming better at coding.

I will keep your advice.
can you send me links to any website from where I can learn optimization techniques.

amarillion
Member #940
January 2001
avatar

Glad to see you're learning.

Move the strlen call in front of the for loop. It only needs to be calculated once.

Indeed, that's what I meant. It's not going to make any noticeable speed improvement in this example, but it's good to start thinking about efficiency early on.

At my job we recently had an example where a programmer carelessly wrote a quadratic algorithm where linear was possible. This problem wasn't noticed during testing because we only tested with small numbers. But the customer sure was noticing when the program crashed repeatedly and then wouldn't start. Oops.

can you send me links to any website from where I can learn optimization techniques.

Well, there is a lot out there, and optimization is a big topic. If I may be so bold, I recommend you my own tutorial series: https://www.helixsoft.nl/articles/circle/sincos.htm It's not exactly about optimization but you may find it useful anyway.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Get the basics of C programming down first, and then try doing some reading on algorithms. Basic ones like sort and search.

https://en.cppreference.com/w/

https://www.khanacademy.org/computing/computer-science/algorithms

http://bigocheatsheet.com/

The large part of optimization is in picking algorithms that are suitable for your purposes, and don't take longer than they need to. amarillion was mentioning the difference between a quadratic complexity and linear. Linear beats quadratic all the time.

In fact, I'm sure I lost an opportunity to work at Google because I didn't optimize my algorithm. I used two for loops instead of one, which is inefficient.

Doctor Cop
Member #16,833
April 2018
avatar

Thanks amarillion and Edgar Reynaldo.
I'll look into it.

GullRaDriel
Member #3,861
September 2003
avatar

Moreover, learn how to profile your code to know where optimization really needs to be done.

http://www.network-theory.co.uk/docs/gccintro/gccintro_80.html
https://www.thegeekstuff.com/2012/08/gprof-tutorial

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Audric
Member #907
January 2001

The first step of optimization is knowing what your code does, don't bother too much about the rest too early. Ie. in my opinion you shouldn't bother trying profiling by yourself, because the results are not meaningful when you're measuring very small amounts (Such as strlen() of strings under 1000 characters, or the comparison between one addition and one square root)
Just know that it's there, when you hit a visible performance question.

Sometimes arrays are more readable (and thus fool-proof), sometimes pointers are.
In this case, this part:

    for(int j=0; j<strlen(string); j++)
    {
        if(string[j] <= '9' && string[j] >= '0')
            count[(int)(string[j]-'0')]++;
    }

can be replaced quite nicely with :

    for(char* c=string; *c != '\0'; c++)
    {
        if(*c <= '9' && *c >= '0')
            count[(int)(*c-'0')]++;
    }

You should read this code as : "c is a pointer that initially points at the first character. *c is the value of the pointed character. c++ moves the pointer, and we loop until we reach the NULL character."

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

bamccaig
Member #7,536
July 2006
avatar

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.

In this case, the for-loop is easily improved by moving the strlen() to the initialization step (but only because the length of the string doesn't change during the loop) and storing it. And that's a very common thing that programmers screw up, and an easy way to save some CPU cycles. Often it won't significantly impact the performance, but it's just as easy if not easier to read the program when you restructure it so it's an easy win.

Just today I was working on some scheduling code at work and checking database state through an ORM layer to determine which UI to render on each day of the month (and later, which functions should be permitted on each day, versus rejected). I looped through the dates visible on the calendar and checked each one. I did my best to preload the memory cache with the database records, but the framework isn't so reliable at obeying your command. I'm not even certain if my function was querying the database again or loading from cache, but I suspect cache. It was very fast in development, but the database is small and hosted on the same machine so it's possible it'll be worse in production. Nevertheless, if it's good enough then it's good enough. Often adding more hardware to run slow or bloated code is cheaper than maintaining micro-optimized code. Pretty much don't solve the problem until it becomes a problem (unless the better solution is obvious, and better, such as above).

Also, isdigit is not strictly 0-9. It is defined according to the selected locale, which means it might act strangely in certain locales, and in particular since we're translating the character into a memory address offset that's a pretty dangerous assumption to make. This is sort of like using \d in regular expressions. Depending on the language, that can sometimes include many other types of characters than strictly 0-9. You're much better off to be explicit and guarantee that the program will do what you intend unless the documentation/specification is explicit about the meaning of the functionality you're using.

Ariesnl
Member #2,902
November 2002
avatar

Also Highly recommended :

https://www.programiz.com/c-programming

https://www.learncpp.com/

( And grab a good book )

Perhaps one day we will find that the human factor is more complicated than space and time (Jean luc Picard)
Current project: [Star Trek Project ] Join if you want ;-)

Doctor Cop
Member #16,833
April 2018
avatar

Now I have completed C language and now I want to work on some projects.

Please help me get started.
Can I contribute to Allegro 5?
What it takes to contribute to a project?

Please help me.

GullRaDriel
Member #3,861
September 2003
avatar

It takes understanding the already exising code ^^

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Now I have completed C language

Making this kind of statement implies you don't actually know C as well as you think you do.

Go to https://en.cppreference.com/w/c and see how much you actually know.

Then learn C++. Then C#.

Then come back to C.

If you want to contribute to an open source project, you need to follow their coding conventions such as formatting and indentation and naming schemes. Then you need to understand what their current code does before you start trying to make contributions. Start small and submit patches. Knowing how to use diff and patch is essential. Unless you've been brought up spoiled and you only know how to use a Github pull request. Learn git. Versioning control systems (VCS) allow you to save and modify your work without fear of losing work you've already committed.

But I suggest you start small and work your way up to larger projects.

Learn interactive console programming first. After that, make some simple graphical applications using your favorite library (Allegro of course!). Then move on to bigger projects, but only after you've gained experience making smaller applications.

jmasterx
Member #11,410
October 2009

Now I have completed C language

Care to explain:
Pointers
Pointer arithmetic
Function pointers
Heap vs Stack
Dynamic vs static memory allocation
Polymorphism and how it is implemented in C
The extern keyword
static vs dynamic libraries
struct padding
opaque data types
How many bytes is an int vs a long?

bamccaig
Member #7,536
July 2006
avatar

The naysayers make valid points, but that's all beside the point. If you're serious about contributing to a project, or doing anything at all in life, you should go for it balls out and try. Nothing will be accomplished by giving up.

Think you can fix a bug or make something better? Allegro is open source. Download the code or better yet clone the Git repo so you have the full history and a mechanism to stay up to date. Learn to build from source and learn to use Git to fetch updates and branch changes. And go ahead and make your changes in a new branch. Test it. Test it again. Try to break it.

If it works and it's as good as you can do, and you think it's valuable to the project, then research how the developers prefer contributions to be submitted. Often projects have a CONTRIBUTE or HACKING file in the root of the repo that details that. If not, check the README, the Web site, and wherever else you can think of. If you can't find an answer then ask somewhere. Here, on the liballeg.org forums, on the mailing list, or in IRC. Somebody will know and guide you toward it.

Submit your patch for consideration, review, comments, and criticism. Expect it to be rejected, but take the suggestions to heart and make the changes requested by the developers. You can always continue working on your change and resubmit it after addressing the concerns.

That's basically what the process is on anything you want to accomplish in life. Try it. Fail. Try again. Repeat. Eventually, you will achieve.

It can take weeks or months to familiarize yourself with a new nontrivial codebase. You should aim low to start out. If you set your goal too high you won't be able to reach it without a lot of dedicated work over a long time. If you are passionate about it then you can do it so go for it. But if you aren't passionate about it and just want to contribute immediately then look for little things you can do. Submitting small documentation improvements is an easy way to get involved. Over time, if you keep at it, you'll learn a lot and your experience will prepare you for better things.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

All of what bambams is saying is true.

However, you lack both knowledge, and experience. Start with knowledge, and then gain experience using that knowledge.

Allegro 4 was hard enough to follow, let alone Allegro 5. There are a ton of A) vtables (virtual function lookup tables), B) Opaque structs, C)Platform specific drivers, D) Addons, E)Private headers and private implementations, etc...

Learn how to use grep. That is your single biggest ally in debugging errors other than a debugger. Which means, you also need to learn GDB, or MSVC's debugger. grep allows you to search for specific string expressions inside groups of files. A debugger allows you to step through code, and observe the state during crashes by getting a backtrace and examining local variables.

You need to learn basic data structures, or at least what their attributes are, and when to use them.

You need to understand basic algorithms like search and sort and their complexity requirements.

By all means contribute to Allegro. But don't expect it to be as easy as you might think it would be at first.

Doctor Cop
Member #16,833
April 2018
avatar

jmasterx: I get it what you want to say, yes I have completed most of the concepts you mentioned.

1. pointers.
2. Pointer arithmetic
3. Function pointers
4. Heap vs Stack
5. Dynamic vs static memory allocation
6. The extern keyword
7. static vs dynamic libraries
8. How many bytes is an int vs a long?

Others I will, thank you for pointing out.
I didn't knew they even exist.

Please tell me more so I can improve.

jmasterx
Member #11,410
October 2009

bamccaig said:

The naysayers

Thanks BamBam >:(

Now that you've mastered the basics, you'll mostly just want to get out there and start coding something.

Most of a dev's time is spent reading code, not writing it. So really focus on coming up with clear ways to structure your code.

Master the art of automated testing (Unit, integration, component, end to end) early on because testing gives you confidence in the code you write and it documents your software's behavior. Even if the project you're contributing to does not have tests, make the code you modify testable and test your code.

If you can write clear, modular, well tested, and well documented code (not comments in the code, automated tests, and meaningful function names), you're sure to be successful.

Doctor Cop
Member #16,833
April 2018
avatar

Thaks jmasterx.
You made my day, I will do a project soon but right now I am learning git,
bash, profiling, gdb.

Not at ones, one by one.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I don't know what the state of profilers on Linux is these days. Last time I tried to use gprof it was horribly borked it just didn't work.

EDIT
Profiling is really not necessary in the beginning stages of a programs development. What you want to do is get something working quickly, and cleanly, even if it isn't complete. Build it in stages. Build one stage upon the other. Then once you have a stable product, start stress testing it. Feed it larger inputs, make it work hard. Unit tests are one of the great things about Java. JUnit makes testing easy. Once you see some performance problems, or bottlenecks in your processing, then start profiling.

Doctor Cop
Member #16,833
April 2018
avatar

Can anybody tell me how can I change my DP?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

 1   2 


Go to: