C C++最全C语言printf函数是怎么解析格式化字符串的?_fioformatv(1),2024年最新阿里、腾讯大厂C C++面试必问知识点系统梳理

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

		doLongLongInt = TRUE;
		goto reswitch;
		}

#endif /*_WRS_E500_FIXED_POINT_SUPPORT /
else
{
doLongInt = TRUE;
goto reswitch;
}
#ifdef _WRS_E500_FIXED_POINT_SUPPORT
case ‘R’: /
e500 fixed point /
e500_sign_flag = 0; /
unsigned fixed point value /
/
FALLTHROUGH /
case ‘r’: /
e500 fixed point */
sign = EOS;
cp = buf;

	    if (e500_sign_flag) {
	        ulongLongVal = SARG();
	        if ((long long)ulongLongVal < 0) 
		   {
		   ulongLongVal = -ulongLongVal;
		   sign = '-';
	 	   }
	    }
	    else ulongLongVal = UARG();

	    if (doShortInt) {
	        ndigs = 5;
	        ulongLongVal <<= (32+16);		
	    } else if (!(doLongLongInt)) {
	        ndigs = 10;
		ulongLongVal <<= 32;
	    } else {
	        ndigs = 19;
	    }
	    n = 0;
	    if (e500_sign_flag) {
	      if (ulongLongVal & (1LL << 63)) {
		n = 1;
	      }
	      ulongLongVal <<= 1;
	      ndigs--;
	    }
	    *cp++ = n + '0';
	    *cp++ = '.';
	    ndigs = (prec >0 ? prec : ndigs);
	    llconst = ((1LL << (64-1))-1);
	    while (ndigs) {
	      a = (ulongLongVal >> (64-3)) + (ulongLongVal >> (64-1)) ;
	      ulongLongVal  = (ulongLongVal & llconst) + ((ulongLongVal << 2) & llconst);
	      a += (ulongLongVal >> 63);
	      *cp++ = a + '0';
	      ndigs--;
	      ulongLongVal <<= 1;
	    }	
	    *cp = '\0';

	    cp = buf;
	    size = strlen(cp);
	    break;

#endif /* _WRS_E500_FIXED_POINT_SUPPORT */

#ifdef _WRS_ALTIVEC_SUPPORT
case ‘v’:
Collect–;
doVector = TRUE;
goto rflag;
#endif /* _WRS_ALTIVEC_SUPPORT */

    case 'c':

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
vec.vul = va_arg (vaList,__vector unsigned long);
cp = buf;
vp = (unsigned char *)&vec.u8;
i = 15;

		while(i-- > 0) {
		
			*cp++ = *vp++;
			if (C_Separator) *cp++ = C_Separator;
		}
		
		*cp++ = *vp++;

		cp = buf;
		size = 16 + (C_Separator ? 15:0);
		sign = EOS;
	    }
	    else 
	    {

#endif /* _WRS_ALTIVEC_SUPPORT */
(cp = buf) = va_arg(vaList, int);
size = 1;
sign = EOS;
#ifdef _WRS_ALTIVEC_SUPPORT
}
#endif /
_WRS_ALTIVEC_SUPPORT */
break;

    case 'D':
	    doLongInt = TRUE; 			/* FALLTHROUGH */

    case 'd':
    case 'i':

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,doShortInt?8:4);

		if (doShortInt)
			sprintf(cp,vp,vec.s16[0],vec.s16[1],vec.s16[2],vec.s16[3],
				      vec.s16[4],vec.s16[5],vec.s16[6],vec.s16[7]);
		else
			sprintf(cp,vp,vec.s32[0],vec.s32[1],vec.s32[2],vec.s32[3]);
		
		RESET_VECTOR_FMT(vp);
		break;
	    }

#endif /* _WRS_ALTIVEC_SUPPORT */

	    ulongLongVal = SARG();
	    if ((long long)ulongLongVal < 0) 
		{
		ulongLongVal = -ulongLongVal;
		sign = '-';
		}
	    base = DEC;
	    goto number;

    case 'n':
	    /* ret is int, so effectively %lln = %ln */
	    if (doLongLongInt)
		*va_arg(vaList, long long *) = (long long) ret;
	    else if (doLongInt)
		*va_arg(vaList, long *) = ret;
	    else if (doShortInt)
		*va_arg(vaList, short *) = ret;
	    else
		*va_arg(vaList, int *) = ret;
	    continue;				/* no output */

    case 'O':
	    doLongInt = TRUE;			/* FALLTHROUGH */

    case 'o':

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,doShortInt?8:4);

		if (doShortInt)
			sprintf(cp,vp,vec.s16[0],vec.s16[1],vec.s16[2],vec.s16[3],
				      vec.s16[4],vec.s16[5],vec.s16[6],vec.s16[7]);
		else
			sprintf(cp,vp,vec.s32[0],vec.s32[1],vec.s32[2],vec.s32[3]);
		
		RESET_VECTOR_FMT(vp);
		break;
	    }

#endif /* _WRS_ALTIVEC_SUPPORT */
ulongLongVal = UARG();
base = OCT;
goto nosign;

    case 'p':
	    /* The argument shall be a pointer to void.  The
	     * value of the pointer is converted to a sequence
	     * of printable characters, in an implementation
	     * defined manner. -- ANSI X3J11
	     */

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,4);

		sprintf(cp,vp,vec.u32[0],vec.u32[1],vec.u32[2],vec.u32[3]);
		
		RESET_VECTOR_FMT(vp);
		break;
	    }

#endif /* _WRS_ALTIVEC_SUPPORT */
ulongLongVal = (unsigned long long) (unsigned int)
va_arg(vaList, void );/ NOSTRICT */
base = HEX;
xdigs = “0123456789abcdef”;
doHexPrefix = TRUE;
ch = ‘x’;
goto nosign;

    case 's':
	    if ((cp = va_arg(vaList, char *)) == NULL)
		cp = "(null)";

	    if (prec >= 0) 
		{
		/* can't use strlen; can only look for the
		 * NUL in the first `prec' characters, and
		 * strlen() will go further.
		 */

		char *p = (char *)memchr(cp, 0, prec);

		if (p != NULL) 
		    {
		    size = p - cp;
		    if (size > prec)
			size = prec;
		    }
		else
		    size = prec;
		}
	    else
		size = strlen(cp);

	    sign = EOS;
	    break;

    case 'U':
	    doLongInt = TRUE;			/* FALLTHROUGH */

    case 'u':

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,doShortInt?8:4);

		if (doShortInt)
			sprintf(cp,vp,vec.u16[0],vec.u16[1],vec.u16[2],vec.u16[3],
				      vec.u16[4],vec.u16[5],vec.u16[6],vec.u16[7]);
		else
			sprintf(cp,vp,vec.u32[0],vec.u32[1],vec.u32[2],vec.u32[3]);
		
		RESET_VECTOR_FMT(vp);
		break;
	    }

#endif /* _WRS_ALTIVEC_SUPPORT */
ulongLongVal = UARG();
base = DEC;
goto nosign;

    case 'X':
	    xdigs = "0123456789ABCDEF";
	    goto hex;

    case 'x':
	    xdigs = "0123456789abcdef";

hex:
#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,doShortInt?8:4);

		if (doShortInt)
			sprintf(cp,vp,vec.s16[0],vec.s16[1],vec.s16[2],vec.s16[3],
				      vec.s16[4],vec.s16[5],vec.s16[6],vec.s16[7]);
		else
			sprintf(cp,vp,vec.s32[0],vec.s32[1],vec.s32[2],vec.s32[3]);
		
		RESET_VECTOR_FMT(vp);
		break;
	    }

#endif /* _WRS_ALTIVEC_SUPPORT */
ulongLongVal = UARG();
base = HEX;

	    /* leading 0x/X only if non-zero */

	    if (doAlt && (ulongLongVal != 0))
		doHexPrefix = TRUE;

	    /* unsigned conversions */

nosign: sign = EOS;

	    /* ... diouXx conversions ... if a precision is
	     * specified, the 0 flag will be ignored. -- ANSI X3J11
	     */

number: if ((dprec = prec) >= 0)
doZeroPad = FALSE;

	    /* The result of converting a zero value with an
	     * explicit precision of zero is no characters. 
	     * -- ANSI X3J11
	     */
	    cp = buf + BUF;
	    if ((ulongLongVal != 0) || (prec != 0)) 
		{
		/* unsigned mod is hard, and unsigned mod
		 * by a constant is easier than that by
		 * a variable; hence this switch.
		 */
		switch (base) 
		    {
		    case OCT:
			do 
			    {
			    *--cp = to_char(ulongLongVal & 7);
			    ulongLongVal >>= 3;
			    } while (ulongLongVal);

			/* handle octal leading 0 */

			if (doAlt && (*cp != '0'))
			    *--cp = '0';
			break;

		    case DEC:
			/* many numbers are 1 digit */

			while (ulongLongVal >= 10) 
			    {
			    *--cp = to_char(ulongLongVal % 10);
			    ulongLongVal /= 10;
			    }

			*--cp = to_char(ulongLongVal);
			break;

		    case HEX:
			do 
			    {
			    *--cp = xdigs[ulongLongVal & 15];
			    ulongLongVal >>= 4;
			    } while (ulongLongVal);
			break;

		    default:
			cp = "bug in vfprintf: bad base";
			size = strlen(cp);
			goto skipsize;
		    }
		}

	    size = buf + BUF - cp;

skipsize:
break;

    case 'L':
	    /* NOT IMPLEMENTED */
	    goto rflag;

    case 'e':
    case 'E':
    case 'f':
    case 'g':
    case 'G':

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,4);

		sprintf(cp,vp,vec.f32[0],vec.f32[1],vec.f32[2],vec.f32[3]);
		
		RESET_VECTOR_FMT(vp);
		break;
	    }

#endif /* _WRS_ALTIVEC_SUPPORT /
if (fioFltFormatRtn != NULL)
{
oldprec = prec; /
in case of strange float */

		if (prec > MAXFRACT) 	/* do realistic precision */
		    {
		    if (((ch != 'g') && (ch != 'G')) || doAlt)
			fpprec = prec - MAXFRACT;
		    prec = MAXFRACT;	/* they asked for it! */
		    }
		else if (prec == -1)
		    prec = 6;		/* ANSI default precision */

		cp  = buf;		/* where to fill in result */
		*cp = EOS;		/* EOS terminate just in case */

#if ((CPU_FAMILY != I960) && (CPU_FAMILY != PPC))
size = (fioFltFormatRtn) (&vaList,prec,doAlt,ch,
&doSign,cp,buf+sizeof(buf));
#else
size = (fioFltFormatRtn) (vaList, prec, doAlt, ch,
&doSign,cp,buf+sizeof(buf));
#endif
if ((int)size < 0) /
strange value (Nan,Inf,…) /
{
size = -size; /
get string length /
prec = oldprec; /
old precision (not default)
/

		    doZeroPad = FALSE;	/* don't pad with zeroes */
		    if (doSign)		/* is strange value signed? */
			sign = '-';
		    }
		else
		    {
		    if (doSign)		
			sign = '-';

		    if (*cp == EOS)
			cp++;
		    }
		break;
		}
	    /* FALLTHROUGH if no floating point format routine */

    default:			/* "%?" prints ?, unless ? is NULL */
	    if (ch == EOS)
		return (ret);

	    /* pretend it was %c with argument ch */

	    cp   = buf;
	    *cp  = ch;
	    size = 1;
	    sign = EOS;
	    break;
    }

/* All reasonable formats wind up here.  At this point,
 * `cp' points to a string which (if not doLAdjust)
 * should be padded out to `width' places.  If
 * doZeroPad, it should first be prefixed by any
 * sign or other prefix; otherwise, it should be blank
 * padded before the prefix is emitted.  After any
 * left-hand padding and prefixing, emit zeroes
 * required by a decimal [diouxX] precision, then print
 * the string proper, then emit zeroes required by any
 * leftover floating precision; finally, if doLAdjust,
 * pad with blanks.
 */

/*
 * compute actual size, so we know how much to pad.
 * fieldsz excludes decimal prec; realsz includes it
 */

fieldsz = size + fpprec;

if (sign)
    {
    fieldsz++;
    if (fieldSzIncludeSign)
        dprec++; 
    }
else if (doHexPrefix)
    fieldsz += 2;

realsz = (dprec > fieldsz) ? dprec : fieldsz;

/* right-adjusting blank padding */

if (!doLAdjust && !doZeroPad)
    PAD(width - realsz, blanks);

/* prefix */

if (sign)
    {
    if ((*outRoutine) (&sign, 1, outarg) != OK)
	return (ERROR);
    }
else if (doHexPrefix) 
    {
    ox[0] = '0';
    ox[1] = ch;
    if ((*outRoutine) (ox, 2, outarg) != OK)
	return (ERROR);
    }

/* right-adjusting zero padding */

if (!doLAdjust && doZeroPad)
    PAD(width - realsz, zeroes);

/* leading zeroes from decimal precision */

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

;
}

/* right-adjusting zero padding */

if (!doLAdjust && doZeroPad)
    PAD(width - realsz, zeroes);

/* leading zeroes from decimal precision */

[外链图片转存中…(img-LMmXMwwk-1715684501117)]
[外链图片转存中…(img-tbttUtSi-1715684501117)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值