Four Arrays (2) Advanced Applications and Characters and Character Arrays

4. Array (2) Advanced Applications and Characters and Character Arrays

1. Array-table-driven method-bool type

Table-driven method is also called table-driven and table-driven method. “Table” is a very useful data structure that is discussed in almost all data structure textbooks. The table-driven approach is a method that allows you to look up information in a table without having to use a lot of logical statements (if or case) to find it.

How can we calculate the number of days in a certain month of a certain year? The stupider way is to use if and switch statements to perform multiple judgments

  • Dumb way to redundantly

    int iGetMonthDays(int iMonth) { int iDays; if(1 == iMonth) {iDays = 31;} else if(2 == iMonth) {iDays = 28;} else if(3 == iMonth) {iDays = 31;} else if(4 == iMonth) {iDays = 30;} else if(5 == iMonth) {iDays = 31;} else if(6 == iMonth) {iDays = 30;} else if(7 == iMonth) {iDays = 31;} else if(8 == iMonth) {iDays = 31;} else if(9 == iMonth) {iDays = 30;} else if(10 == iMonth) {iDays = 31 ;} else if(11 == iMonth) {iDays = 30;} else if(12 == iMonth) {iDays = 31;} return iDays; }

This leads to what I want to explain, table-driven solution!

#include<stdio.h>
#include<stdbool.h> //The header file that the bool data type must include
int getdays(int,int);
bool is_leapyear(int);
int main()
{<!-- -->
int month = 0;
int year = 0;
scanf("%d %d", & amp;month, & amp;year);
printf("%d", getdays(month-1, year));
return 0;
}
int getdays(int month, int year)
{<!-- -->
int months[12] = {<!-- --> 31,is_leapyear(year) ? 29: 28 ,31,30,31,30,31,31,30,31,30,31 };
return months[month];
}
bool is_leapyear(int year)
{<!-- -->
if ((0 == year % 4 & amp; & amp; year % 100 != 0) || (0 == year % 400))
return true;
else return false;
}

What if we want to be more streamlined?

#include<stdio.h>
#include<stdbool.h>
int getdays(int,int);
int main()
{<!-- -->
int month = 0;
int year = 0;
scanf("%d %d", & amp;month, & amp;year);
printf("%d", getdays(month-1, year));
return 0;
}
int getdays(int month, int year)
{<!-- -->
int months[12] = {<!-- --> 31,(false == year % 4 & amp; & amp; year % 100 != true) || (0 == year % 400) ? 29: 28 ,31,30,31,30,31,31,30,31,30,31};
return months[month];
}

Detailed explanation:

#include<stdio.h>
#include<stdbool.h> //The header file that the bool data type must include
int getdays(int,int);
bool is_leapyear(int);
int main()
{<!-- -->
int month = 0;
int year = 0;//table driven method
scanf("%d %d", & amp;month, & amp;year);
printf("%d", getdays(month-1, year));
return 0;
}//Returns the number of days in each month, relying on the is_leapyear function
int getdays(int month, int year)
{<!-- -->//Perform operations on array elements, omitting a large number of conditional statements
int months[12] = {<!-- --> 31,is_leapyear(year) ? 29: 28 ,31,30,31,30,31,31,30,31,30,31 };
return months[month];
}
bool is_leapyear(int year)//determine whether it is a leap year
{<!-- -->
if ((0 == year % 4 & amp; & amp; year % 100 != 0) || (0 == year % 400))
return true;
else return false;
}

2. Enumeration

–Although this is an independent section, it is similar to arrays, so I will put it here.

Enumeration actually means omitting cumbersome macro definitions and assigning values to enumerated elements at once. Enumeration types are very commonly used.

An enumerated type in C is a user-defined data type that allows programmers to assign easy-to-remember names to integer values to improve code readability and maintainability. An enumeration type is defined after the enum keyword and is surrounded by a pair of curly braces, inside which is a series of named integer constants.

The following is the basic syntax for enumeration types:

enum enumeration name {<!-- -->
    Name 1,
    Name 2,
    Name 3,
    // ... other names
};

Each name (also called an enumerator) corresponds to an integer value. By default, the first enumerator has a value of 0, and subsequent enumerators have values that are incremented. You can also manually specify specific values for the enumerator:

enum enumeration name {<!-- -->
    Name1 = 10,
    Name 2, // value is 11
    Name 3 = 20,
    Name 4, // value is 21
    // ... other names
};

In this example, Name1 is assigned the value 10, and Name2 has no value specified, so its value is Name1< Add 1 to the value of /code>, which is 11. Name3 is assigned the value 20, and Name4 is 21.

Enumeration types are often used to represent a set of related constant values, such as status codes, error codes, or specific mode selections. Using enumeration types can be more clear and organized than using #define or ordinary constant definitions.

In actual use, you can use enumeration variables just like ordinary integer types, for example:

enum day {<!-- -->SUN, MON, TUE, WED, THU, FRI, SAT};

int main() {<!-- -->
    enum day today = WED;
    if (today == WED) {<!-- -->
        // perform some operations
    }
    return 0;
}

In this example, we define an enumeration type named day, which contains the seven days of the week, and then we declare a variable of type enum daytoday, and assign the value to WED. In the if statement, we can directly use the enumeration value for comparison.

There are several advantages to using enumeration types:

  • Code is easier to understand and maintain because enum values are more descriptive than bare integers.
  • Enumeration types are type-checked by the compiler, which helps reduce errors.
  • Enumerations can be displayed more clearly with the debugger for easier debugging.

In summary, an enumeration is a concise and powerful data structure in C language, suitable for managing a set of named integer constants.

3. String

  • A string of characters ending with 0 (positive number 0), 0 or \0’ are the same, but different from 0’
  • 0 marks the introduction of the string, but it is not part of the string
  • Zero should not be included when calculating string length
  • Strings exist in the form of arrays and are accessed in the form of arrays or pointers, more in the form of pointers
  • The header file string.h has many functions for processing strings.

Important points:

  • Strings in C language exist in the form of character arrays
  • Operators cannot be used on strings
  • Strings can be traversed through arrays
  • The only special thing is that string literals can be used to initialize character arrays
  • If two strings are written consecutively, C language will help us connect them.

3.1String constants

char* s = "hello,world";

  • s is a pointer, initialized to point to a string constant
  • Because of the location of this constant, s is actually const char * s. However, due to historical reasons, the compiler accepts writing without const.
  • But trying to write/modify the string pointed to by s will lead to serious consequences.
  • If you need to modify the string, you should use an array: char s[] = “hello,world”;

char line[10] = "hello"; line[1] = 'b'; printf("%s",line);

Let me give an example: char *s1 = “hello”; char *s2 = “hello”;

So pointer or array?

Basic idea: If you want to construct a string → array; if you want to process a string → pointer;

For arrays:

  • This string is right here
  • As local variable space is automatically reclaimed

For pointers:

  • I don’t know where this string is
  • Process parameters and dynamically allocate space

Final things to remember:

  • A string can express the form of char, but char is not necessarily a string. The original intention is a pointer to a character, which may point to an array of characters (just like int*)
  • Only when the character array pointed to by char* has a trailing 0, can it be said that it points to a string.

3.2 String array

int main()
{<!-- -->
//char[10]; a[0] is equivalent to a char[10]

//a[0] is equivalent to cha*
char a[][10] = {<!-- --> "hello", "world",};
char *b[10] = {<!-- --> "hello", "world", };
return 0;
}//The output results are the same

So what is the difference between these two ways of writing?

  • main function parameters

    *1. Under what circumstances should int main(int argc, char argv[]) be used?

    We need to interact with the program. You know, during the running of the program, you can use the scanf function to input arrays, characters, and strings for the program to process.

    So can you bring parameters to the program when it starts (), instead of typing things into the program during operation? At this time, you need to use the main function with parameters (int argc, char *argv[]).

    You have probably used the ping command to ping an IP address, for example: ping 192.168.0.1

    In fact, the ping here is an exe program, and “192.168.0.1” is a string, which is the parameter we pass to the program.

    Therefore, when you need the program to start with parameters, use int main(int argc, char *argv[]).

    2. How to use argc and argv parameters.

    You may think that argc and argv are parameters passed to the main function. Who passed this parameter? Isn’t the main function already the entry function? Are there other functions that call the main function?

    argc and argv are what you pass to the program through the command line window.

    Can you guess what the result of the following program is?

    #include int main(int argc , char *argv[]) { printf("argc = %d\
    ", argc); printf("%s\
    ", *argv); }

    We compile and run, and the results are as follows. Have you noticed that *argv is a string, and the content of the string is the exe program file name (including its full path).

    https://pic1.zhimg. com/80/v2-3356895f884e36e22224d79e354e099c_1440w.webp

    argc = 1, what does this mean? It means that the command line has a string. This string is “D\test\main_arg_argv.exe”, which is our program name.

    You might be thinking:

    (1) How to pass a string to the program through the command line?

    (2) How does the program obtain the passed string?

    the answer is:

    (1) Pass the string to the program in this format:

    Program name.exe string 1 string 2 string 3… string n

    When executing an exe program, you can add any number of strings after the .exe name. Separate each string with spaces.

    (2) In the main function, receive strings one by one through a loop.

    for example:

    Let’s make a program like this:

    Require:

    If a string passed is equal to “Aa”, “A for apple” will be printed; if a string passed is equal to “Bb”, “B for ball” will be printed; if a string passed is equal to “Cc”, ” C for ball”, if a string passed is equal to “Dd”, it will output “D for dog”.

    First the code:

    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, int *argv[])
    {<!-- -->
        printf("argc = %d\
    ", argc);
    
        argv + + ;
        while (*argv){<!-- -->
            if (strcmp(*argv, "Aa") == 0){<!-- -->
                argv + + ;
                printf("A for apple\
    ");
    
            }else if (strcmp(*argv, "Bb") == 0){<!-- -->
                argv + + ;
                printf("B for ball\
    ");
    
            }else if (strcmp(*argv, "Cc") == 0){<!-- -->
                argv + + ;
                printf("C for cat\
    ");
    
            }else if (strcmp(*argv, "Dd") == 0){<!-- -->
                    printf("in d\
    ");
                argv + + ;
                printf("D for dog\
    ");
            }
        }
    }
    

    Note that at this time, we cannot run the program directly in the editor, because there are no parameters for automatic operation.

    Click the compile button in the picture below. Then enter the folder where the source file is located: D:\test. You can see that a file named main_argc_argv.exe is generated. This is the executable file generated by compilation, commonly known as “program/software”.

    https://pic4.zhimg. com/80/v2-3ea84a6ed2b5a73f1257345597f63313_1440w.webp

    D:\test\main_argc_argv.exe

    https://pic2.zhimg. com/80/v2-4388b2b94f1ae770736a8369e7f70579_1440w.webp

    So how does it work?

    Open the command line, select the .exe file with the left mouse button, and drag it to the cmd window:

    https://pic4.zhimg.com/80/v2-1869ede62211232bac5792f6d9e6260f_1 440w.webp

    Then add the string we want to add at the end. Add “Cc” and “Aa” here

    https://pic1.zhimg.com/80/v2-a145fa9d94776ec96d9c5a6015198e60_1 440w.webp

    Then, press Enter to run.

    https://pic2.zhimg. com/80/v2-999e3972a22bee800a70861b6345b975_1440w.webp

    As we expected, when we type parameters on the command line, Cc is in front of Aa, so “C for cat” is printed first, and then “A for apple” is printed.

    Note: argc here is 3, what does it mean?

    As we said before, when arrgc=1, it means that the command line has only one string, which is the program name “D\test\main_arg_argv.exe”.

    3 means that the command line has three strings, namely: program name “D\test\main_arg_argv.exe”, “Cc” and “Aa”.

    Now you should understand how to use the parameters in the main function.

    3. Summary

    When you need the program to start with parameters, use int main(int argc, char *argv[]).

4. Use of string functions

4.1 strcmp is used to compare two strings

  • Compares two strings and returns:
  • 0: s1==s2; 1: s1>s2; -1: s1

Arrays cannot be compared directly because their addresses are different. Why does printf return 0? Think about the printf mentioned before that will return the number of bytes of the number of parameters! , because it cannot be compared, it is always false!

4.2strcpy

  • Function prototype: char*(charrestrict det, const charrestrict src);
  • Copy the latter string to the previous character, restrict indicates that the two strings cannot overlap
  • Returns the copied character dst, this is to chain the code

Usage: char det = (char)malloc(strlen(src) + 1);

 strcpy(dst,src);

4.3 Finding characters in strings

5. Dynamic memory allocation

#include<stdio.h>
#include<stdlib.h>//Used to export the malloc function

int main_9()
{<!-- -->
int number;
int* a;
int i;
scanf("%d", & amp;number);
// int a[number];
a = (int*)malloc(number * sizeof(int));//Use a as an array (int*) type conversion, because malloc is followed by void
for (i = 0; i < number; i + + ) {<!-- --> //Treat as an array.
scanf("%d", & amp;a[i]);
}
for (i = number - 1; i >= 0; i--) {<!-- -->
printf("%d", a[i]);
}
free(a); //Return the space. You can only return the first address of the applied space.
\t

return 0;
}
int main_9_2(void)//Detect allocated space size
{<!-- -->
void* p;
int cnt = 0;
while ((p = malloc(100 * 1024 * 1024)))
{<!-- -->
cnt + + ;
}
printf("?0MB space allocated", cnt);
return 0;
}

Frequently Asked Questions: Is it free after applying → Memory gradually decreases after long-term operation

Novice: Forgot; Veteran: Can’t find the right time to free; Free after free; Go to free directly after the address has changed;

int main(void)
{<!-- -->
int i;
void* p;
int cnt = 0;
p = malloc(100 * 102400);
p + + ;
free(p);} // The address of p has changed, and free here is an invalid code

We use free(NULL) to prevent the program from doing anything! This is also good practice.

We must remember to add free!

6. Input and output of single characters

6.1 putchar()

  • Function prototype: int putchar(int c);
  • Write a character to standard output
  • Returns how many characters have been written. EOF (-1) indicates writing failure.

In the win system environment, enter: CTRL + Z to indicate input failure.

//Common models:
while((ch = getchar())!=EOF){<!-- -->//This returns the EOF program to end the loop
putchar(ch);
}

The reason is that there are input and output buffers.

6.2getchar()

  • Can only read a single character
  • Function prototype: int getchar(void);
  • The return type is int to return EOF (-1)

In the win system environment, enter: CTRL + Z to indicate input failure.

7. String input and output

In C language, string input is usually implemented through the standard input function. The most common methods are to use the scanf function or the gets function. However, it should be noted that using these functions requires careful handling of buffer overflow issues. Here are some common string input methods:

  1. Using the scanf function:
    The scanf function can be used to read formatted input from standard input (usually the keyboard). When used with strings, it is typically used with the %s formatting identifier. For example:

    char str[100];
    printf("Enter a string: ");
    scanf("?s", str); // Note that ?s is used here to avoid buffer overflow
    
    

    However, it should be noted that scanf cannot handle line breaks, spaces, tabs, etc. Therefore, when using scanf, you must ensure that there are no line breaks, spaces, tabs, etc. in the string.

  2. Using the gets function:
    The gets function reads a line of text until a newline character is encountered. However, gets is unsafe because it does not check the size of the target buffer and can easily cause buffer overflow. Therefore, it has been deprecated in the latest C standard. If you still want to use it, the code is as follows:

    char str[100];
    printf("Enter a string: ");
    gets(str); // Not recommended because of security risks
    
    
  3. Using the fgets function:
    As a safe alternative to gets, the fgets function reads a line from a file or standard input until a newline character is encountered or a specified number of characters is reached. It checks the buffer size to avoid overflow. For example:

    char str[100];
    printf("Enter a string: ");
    fgets(str, sizeof(str), stdin); // safe, recommended
    
    

In actual programming, it is recommended to use the scanf (remember to limit the input length) or the fgets function, because they are safer and can prevent buffer overflow problems.

These three functions will automatically complete '\0' at the end of the string, which is NULL

In practice, gets and puts are often used together.

puts function

The puts function is used to output a string to standard output (usually the screen), and automatically adds a newline character after the output string.

cCopy code
char str[] = "Hello, world!";
puts(str); // Output the string str and add a newline character at the end

The puts function is relatively safe because it does not involve writing to a buffer. It simply outputs an existing string and adds a newline character at the end.

To sum up, although gets and puts are paired functions, due to gets security risks, it is recommended to use fgets instead of gets, and < strong>puts can continue to be used to output strings.

syntaxbug.com © 2021 All Rights Reserved.