Joshy 4,364 / 44,927 Report Post Posted May 5, 2019 Edited December 1, 2019 by Joshy - Edit Reason: New followup thread I covered last time how to run parts of your program conditionally, and how to loop through it repeatedly instead of retyping the same code over and over again. These next tools will help improve the legibility of your code and its elegance. We previously looked at conditions with two prominent outcomes: (1) It's true, or (2) it's false. What if you have many conditions or options to choose from? Something like below: You could approach this using the brute force method you are already familiar with by cascading many if-else statements together, and it would work. #include <stdio.h> int main() { int userSelection; printf("Choose a case [1-5]: "); scanf("%i", &userSelection); if(userSelection == 1) { printf("You chose 1."); } else if(userSelection == 2) { printf("You chose 2."); } else if(userSelection == 3) { printf("You chose 3."); } else if(userSelection == 4) { printf("You chose 4."); } else if(userSelection == 5) { printf("You chose 5."); } else { printf("Not a valid case!"); } return 0; } Wouldn't it be nice if there was an alternative way to do this without so many if-else... something a little more straightforward rather than checking through each condition? Something like below? Let us pretend the user only wanted to run case 1. Switch case is your solution, and the syntax is pretty easy. The code here will give you the same output as the earlier cascading if-else. Try running both to see for yourself. You begin each case with "case" followed by the integer (ie. 0, 1, 2... 99) or a character (ie. 'a', 'b'... 'y', 'Y'), and you end each section with "break." If you don't use "break", then it'll run both that particular case and the one(s) below it until it hits a "break" or the end. #include <stdio.h> int main() { int userSelection; printf("Choose a case [1-5]: "); scanf("%i", &userSelection); // userSelection can only be an integer or a single character switch(userSelection) { case 1: printf("You chose 1."); break; case 2: printf("You chose 2."); break; case 3: printf("You chose 3."); break; case 4: printf("You chose 4."); break; case 5: printf("You chose 5."); break; default: printf("Not a valid case!"); } return 0; } This could even ease up the pain of having multiple conditions running the same code. Earlier: You may have noticed that the user selection was case-sensitive. If the user selected lowercase 'y' and you had typed in capital 'Y' into your code for the condition, then it would have not ran that code. You would have to cascade two conditional statements using what I have given you before. printf("Yes or no? [y/n]: "); scanf("%c", &userSelection); if(userSelection == 'y') { printf("The user selected yes."); } else if(userSelection == 'Y') { printf("The user selected yes."); } else { printf("The user selected no."); } // I'm purposefully neglecting to use || (OR) to make a point here This could be made equivalently by using switch case: printf("Yes or no? [y/n]: "); scanf("%c", &userSelection); switch(userSelection) { case 'y': case 'Y': printf("The user selected yes."); break; default: printf("The user selected no."); } Lets run that earlier example of adding numbers using a switch case instead of if-else. You can copy and paste this, and it shouldn't surprise you that it runs exactly the same. #include <stdio.h> int main() { // Declaration and initial values int count = 0, numX = 0, numY = 0; char userSelection; printf("Would you like to add numbers? [y/n]: "); scanf("%c", &userSelection); switch(userSelection) { case 'y': case 'Y': printf("How many numbers would you like to add?: "); scanf("%i", &count); for(int i = 0; i < count; i++) { // User interface printf("Input number to add: "); scanf("%i", &numX); numY = numY + numX; } // Output printf("The sum is: %i", numY); break; case 'n': case 'N': printf("Exiting program."); break; default: printf("You did not select 'y' or 'n'!"); printf("\nExiting program."); } return 0; } The variables you have been working on have only been able to hold one item. It's time for you to expand into the next dimension. It's time for... 1-D? That's it? The strategies and concepts here will work the same way for multi-dimensional sets, but you can still achieve a lot with 1-D compared to working with a single item. Have you ever used Excel or some spreadsheet? Arrays are exactly the same thing. You can hold a set of numbers or characters in a single variable we call an array, and each item or element in the array has a corresponding "index." The above picture is literally from open office (the open source version of Microsoft office). As you can see in the first array I have the second item '2' selected, and the array has a size of 5 items (1, 2, 3, 4, and 5). I made another array with 5 items in it too (3, 7, 8, 10, and 11). One of the more tricky things with arrays is how the computer interprets it. The computer wants to start things at zero (0) instead of one (1), and so an array of 5 items will run through index 0, 1, 2, 3, and 4. The equivalent second item in Array1 would therefore be in index '1' (because '1' is the second index coming after '0').: // The declaration is the name of the array, followed by its [size], and the elements inside of it {element1, element2... } int Array1[5] = {1, 2, 3, 4, 5}; // This would print the second element "2". // The first element in this array is Array1[0] contains a "1"... // ... and the thid element in this array is Array1[2] contains a "3". printf("%i", Array1[1]); Lets try another array just to get a feel for it. #include <stdio.h> int main() { char name[6] = {'J', 'o', 's', 'h', 'y'}; for(int i=0; i<6; i++) { printf("%c", name[i]); } return 0; } Now that we are seeing you can use switch instead of if-else for a large selection, and that you can loop through your arrays instead of using multiple variables, lets explore some other ways to repeat tasks without having to rewrite code multiple times. Learning about functions is SUPER helpful for repeating tasks. This is probably an area of focus if you're interested in developing, and so I suggest paying special attention here and running through the examples if you can. Without functions: The concept of your code will look a lot like below: Implementing functions in your code will have you write that operation only one time although you can use it many times throughout your code As you can see: This is much more elegant and you wont have to rewrite your code over and over again. One could argue, that you could use a loop instead, but imagine if your operation involved some type of loop or you wanted to perform this operation in several loops. This would become a mess. Sometimes you use functions not just to prevent repeating code, but to also make your code legible or easy to understand. Here's an example of a code using a mathematical operation: #include <stdio.h> int main() { int a = 2, b = 3, c = 0; int power(int base, int exponent); // you have to declare your functions too c = power(a, b); printf("%i to the power of %i = %i", a, b, c); return 0; } // <-- End of main program // type name(arguments) <-- Beginning of your function called "power" int power(int base, int exponent) { // base^exponent int output = 1; for(int i=0; i<exponent; i++) { output = output*base; } // this is the output when you call it in the main function return output; } And another example where multiple functions are involved. We'll pretend I want to round numbers to the nearest 10th using another function. #include <stdio.h> int main() { int a = 2, b = 2, c = 0, d = 0; int power(int base, int exponent), round10(int inputNumber); // you have to declare your functions too! c = power(a, b); printf("%i to the power of %i = %i", a, b, c); // Now we will round this number to the nearest 10 d = round10(c); printf("\nRounding to nearest 10th: %i -> %i", c, d); return 0; } // type name(arguments) int power(int base, int exponent) { // base^exponent int output = 1; for(int i=0; i<exponent; i++) { output = output*base; } // this is the output when you call it in the main function return output; } // end of power // beginning of another function called "round10" int round10(int number) { // This function rounds the input number to the nearest multiple of 10 int R = 0, output = 0; // Modulo "%" tells you the "remainder" (R) after something is divided // For example 7%5 is 2. R = number%10; if(R < 5) { // Subtract the remainder rounding DOWN output = number - R; } else { // Add whatever you need to get to then next 10th output = number + (10-R); } return output; } Maybe the function above seems harder than just directly typing in the equation. Lets take a look at some data array examples and use a function that helps us finds the maximum value inside of the array. Using a function makes it easy for me to call "max(arguments)" and so my code is easy to understand, and I don't have to use so many loops to get the job done. #include <stdio.h> int main() { int someArray[5] = {0, 1, 12, 3, 18}, dataSet[7] = {1, 101, 5, 1, 1, 0, 12}, randomNumbers[3] = {3, 2, 1}; int max(int arg[], int size); printf("%i", max(someArray, 5)); printf("\t%i", max(dataSet, 7)); printf("\t%i", max(randomNumbers, 3)); return 0; } int max(int array[], int sizeArray) { // Find maximum value in array[] of a given size // Arbitrarily low value int maxValue = 0; for(int i=0;i<sizeArray; i++) { if(array[i] > maxValue) { // If new value is bigger than old, then set new value to maxValue maxValue = array[i]; } } // This is the output of our function return maxValue; } This stuff was pretty heavy, wasn't it? You could still copy and paste a lot of the code above just to get a feel for it, and to again massage the code or use it as a framework for something else of interest. Here's what I recommend trying: Take that summing example and make a switch that allows the user to select an operation (adding, subtracting, multiply, divide...), and make each option a function such that you have something like this: int add(int X, int Y), multiply; // declare your functions int userSelection; printf("1. Add\n"); printf("2. Multiply\n"); //.. printf("Choose an operation: "); scanf("%i", &userSelection) switch(userSelection) { case 1: add(X, Y); break; case 2: multiply(); break; //.. } return 9001; } // <-- end main int add(int X, int Y) { int outputValue; return X + Y; } int multiply( //.. Try a multi-dimensional array. This is the strategy: // name[row][column] = {elements} someArray[][] = {item1, item2, item3}, // a comma before next row {item4, item5, item6}; Conceptually: Interestingly: You could continue using this style of thinking into 3-D and beyond (4-D, 5-D, ... , 100-D). Try a function that returns a character or a void (one without a return) char someFunction(int argument) { char output; switch(argument) { case 1: output = 'a'; break; //.. } return output; } // void function void otherFunction(char argument2) { //.. } Make a sorting function ie. takes in an array and rearranges all the items in ascending or descending order (I recommend nested loops) Follow up in the next thread to learn more. Edited December 1, 2019 by Joshy New followup thread Share this post Link to post Share on other sites More sharing options...
annoying furry 6,300 / 63,950 Report Post Posted May 6, 2019 bumping to fix last poster. (signature made by @Kaylode) Previously known as Xy. Twitter ❤️Ko-Fi ❤️Github Share this post Link to post Share on other sites More sharing options...
im not inactive you are 888 / 16,340 Report Post Posted May 6, 2019 where were you 2 weeks ago with this, my roommate's head was exploding on matlab lol Former Gmod Prop Hunt Admin Former Media Team Team Leader Former Media Team GFX Member Share this post Link to post Share on other sites More sharing options...
nci 5 / 649 Report Post Posted May 31, 2019 Edited May 31, 2019 by nci - Edit Reason: small addition I realize the point of this was to explain how arrays work but in reality it's better practice to use STL objects, namely vectors in this scenario, when dealing with dynamic allocation, or even just in general. Just as a personal opinion I feel using a vector for these types of things just looks cleaner and more modern, which is something we all should strive for. Regardless, it's a great introduction and explanation, so good job on that! Edit: For multidimensional purposes you can always use a map/unordered map to keep the STL object mindset. Edited May 31, 2019 by nci small addition Share this post Link to post Share on other sites More sharing options...