Variable Parameter Function - Implement Simple Pritf

Click to understand Variable length parameterVariable parameter function

Why can I only implement a simple version of printf, because there are many optimizations involved, such as storage, data structure, output color and so on, and my program only implements an integer module. And there is no improvement, like%d02, and so on, just a design idea, but also the application of variable parameter function

Overall ideas:
1. First implement, print a string of characters, use putchar
2. How to realize the value of the print parameter and use the variable parameter function to get the latter variable
3. Record the number of prints (Fusion 1, 2)
4. Optimizing Code in Continuous Trials and Errors

Let's do it step by step

Function 1: Ability to print a complete string
Here we implement my_based on putchar() Printf, compare with printf
The process generation code is as follows:

#include<stdio.h>

//Before const, the value in the frm is constant, the address is allowed to change, and the value is not allowed to change
int my_printf(const char *frm,...) {    //Receive a String
    int cnt = 0;                        //Record the number of characters printed
    for(int i = 0; frm[i]; i++) {     //A value of 0 at the end of the string is false and traverses to the end naturally
        putchar(frm[i]),++cnt;
    }
    return cnt;
}

int main() {
    printf("hello word\n");
    my_printf("hello word\n");
    return 0;
}

The function implementation of the program is to overlay the code on the original basis, and the best thing about printf is to be able to print the value of a variable, which is based on the ability of a variable parameter function.

Function 2: Print the value of a variable
Procedure two: Idea: First, to parse the string, encounter%,%d,%c, etc., code is limited, only parse the contents of%d,
->Target to achieve print integer 123

Principal function

int main() {
    int a = 123;
    printf("hello word\n");
    my_printf("hello word\n");
    printf("int (a) =%d\n",a);
    my_printf("int (a) =%d\n",a);
    return 0;
}

Print results:

Does it look a bit like that? Let's move on to the third step, because of the uncertainty of the data, we need a variety of errors to debug
Process three: adjustment and trial and error
1 Data Flip: First of all, because the number of bits in the data cannot be determined, we use the method of printing the data from the end, which also results in the reversal of the data from the original data, so we need to flip the data before printing.
Modify:

 case 'd' : {      //Because reshaping cannot be done together, only one bit of output can be in character form
          int x = va_arg(arg, int);
          int temp = 0;
          while(x){
              temp = temp*10 + x % 10;
              x /=10;
          }
          while (temp) {
          	  PUTC(temp % 10 + '0');
              temp /= 10;
            }
  }break;

The results show:

2. Optimizing Input 0 and Negative Numbers
Positive and Negative Judgment Introduced

   				case 'd' : {     
                            int x = va_arg(arg, int);
                            if(x == 0) 
                                {
                                PUTC('0');    
                            }
                            else {  
                                    if(x < 0) x = -x, PUTC('-');
                                    int temp = 0;
                                    while(x){
                                        temp = temp*10 + x % 10;
                                        x /=10;
                                    }
                                    while (temp) {
                                        PUTC(temp % 10 + '0');
                                        temp /= 10;
                                    }

                            }
                        }break;

The result is feasible

3, to solve the problem left over by flipping, input 1000, flip becomes 0001, the final output is 1

Modify the flip section to introduce a variable, digit, number of records

4, output 32-bit integer maximum and minimum, introduce header file #include<inttypes.h>
First result:

Error Reason: Maximum flip exceeds the maximum of 32-bit integers (about 2 billion).
Solution 1: Define a 64-bit integer, but all have limitations
Solution 2: Bitwise representation, where each bit is stored in an array
Solution three: divide the integer into two parts, high and low, this time use the high five-digit, low five-digit form of processing
10 bits can represent 10 million, 10 billion sizes
Optimize Code

After optimization

5. Question optimization with 0 between high and low position i.e. input 100500
Look first at the error results

Error analysis: low 00500, or 500, flipped to 5, digit2 = 3,
Passed

 if(x1) digit2 =5;  //If the top five is not zero, the bottom five will be full, but there may be a gap between the top five and the fifth.

The output process is wrong
Code optimization: 0 for the middle

Function 3: Test if the number of characters printed successfully is correct
The code is as follows: Actually, thanks to having cnt records for each print

int a = 123,n;
	while(~(scanf("%d",&n))) {   //Show number of successful prints
		printf("  has %d digits!\n",printf("%d",n));
		my_printf("  has %d digits!\n",my_printf("%d",n));
	}
	return 0;	

The results are as follows:

Whole program (Output data in program, think about direct forward printing?)

#include<stdio.h>
#include<inttypes.h>
#include<stdarg.h>
#include<limits.h>
#Define PUTC(a) putchar(a), ++cnt //Parse the following format to encapsulate the macro as a function

int revers(int num,int *temp) {
	int  digit = 0;
	do {
		digit++;
		*temp = *temp * 10 + num % 10;
		num /= 10;
	   }while(num); 
	return digit; 
}

 int output_num (int num,int digit) {
 	int cnt = 0;
 	while(digit--) {
 		putchar(num % 10 + '0'), ++cnt;
 		num /= 10;
 	}
 	return cnt;
 }
//Before const, the value in the frm is constant, the address is allowed to change, and the value is not allowed to change
int my_printf(const char *frm,...) {    //Receive a String
	int cnt = 0;
	va_list arg;
	va_start(arg , frm);
	for(int i = 0; frm[i]; i++) {     //A value of 0 at the end of the string is false and traverses to the end naturally
		switch(frm[i]){
			case '%': {
				switch (frm[++i]) {
					case '%' : PUTC(frm[i]); break;  //Because reshaping cannot be done together, only one bit of output can be in character form
					case 'd': {
						int x = va_arg(arg, int);
						uint32_t xx = 0;
						if (x < 0) PUTC('-'), xx = - x;  //Negative Edge Positive Number
						else xx = x;  
						int x1 = xx / 100000, x2 = xx % 100000;  //x1 high five digits, x2 low five digits
						int temp1 = 0, temp2 = 0;
						int digit1 = revers(x1, &temp1);   //Outgoing parameters, the parameters that are passed through the operation; The following temp1,2 is used directly, no longer defining new variables
						int digit2 = revers(x2, &temp2);   //Number of Records 
						int digit3 = 0;  //Record 0 in the middle of 5 lower to 5 higher bits  
						if(x1) digit3 = 5 - digit2;    //If the high bit is not zero, the low five bit is five
						else digit1 = 0;      //Otherwise, the high quintile is zero
						cnt += output_num(temp1,digit1);
						cnt += output_num(0, digit3);
						cnt += output_num(temp2,digit2);
 					} break;
 					case 's' : {
 						const char *str = va_arg(arg, const char *);
 						for(int i = 0; str[i]; i++){
 							PUTC(str[i]);
 						  }
 					} break; 
				} 
			} break;//First%End
			default : PUTC(frm[i]) ; break; //Print directly without meeting%
		}
	} 
	//#undef PUTC //is a PUTC non-PUTC(a)

	va_end(arg);
	return cnt;
}

int main() {
	int a = 123,n;
	while(~(scanf("%d",&n))) {   //Show number of successful prints
		printf("  has %d digits!\n",printf("%d",n));
		my_printf("  has %d digits!\n",my_printf("%d",n));
	}
	return 0;	
	char str[] = "I love china";
	printf("hello word\n");
	my_printf("hello word\n");
	printf("int (a) = %d\n",a);
	my_printf("int (a) = %d\n",a);
	printf("int (a) = %d\n",0);
	my_printf("int (a) = %d\n",0);
	my_printf("int (a) = %d\n",-123);
	printf("int (a) = %d\n",-123);
	printf("int (a) = %d\n",INT_MAX);
	my_printf("int (a) = %d\n",INT_MAX);
	printf("int (a) = %d\n",INT_MIN);
	my_printf("int (a) = %d\n",INT_MIN);
	printf("int (100500) = %d\n",100500);
	my_printf("int (100500) = %d\n",100500);
	
	printf("str = %s\n",str);
	my_printf("str = %s\n",str);

  	
	return 0;
}

Tags: C C++

Posted on Fri, 12 Nov 2021 14:43:08 -0500 by excence