QString

目录

1 toInt()

(1)qt_strtoll()

(2) qstrtoll()

(3)bytearrayToLongLong()

(4)toIntegral_helper

2 static QString number(int, int base=10);

(1)源码

(2)QString longLongToString() const;

(3)QString qulltoa(qulonglong l, int base, const QChar _zero);


1 toInt()

下面是toInt()函数的内部实现源码

QString str("16");
int b  = str.toInt();
//toInt
int QString::toInt(bool *ok, int base) const
{
    return toIntegral_helper(constData(), size(), ok, base);
}
//toIntegral_helper
    template  static
    T toIntegral_helper(const QChar *data, int len, bool *ok, int base)
    {
        // ### Qt6: use std::conditional::value, qulonglong, qlonglong>::type
        const bool isUnsigned = T(0) < T(-1);
        typedef typename QtPrivate::QConditional::Type Int64;
        typedef typename QtPrivate::QConditional::Type Int32;

        // we select the right overload by casting size() to int or uint
        Int64 val = toIntegral_helper(data, Int32(len), ok, base);
        if (T(val) != val) {
            if (ok)
                *ok = false;
            val = 0;
        }
        return T(val);
    }
//toIntegral_helper
qlonglong QString::toIntegral_helper(const QChar *data, int len, bool *ok, int base)
{
#if defined(QT_CHECK_RANGE)
    if (base != 0 && (base < 2 || base > 36)) {
        qWarning("QString::toULongLong: Invalid base (%d)", base);
        base = 10;
    }
#endif

    return QLocaleData::c()->stringToLongLong(QStringView(data, len), base, ok, QLocale::RejectGroupSeparator);
}
//stringToLongLong
qlonglong QLocaleData::stringToLongLong(QStringView str, int base, bool *ok,
                                        QLocale::NumberOptions number_options) const
{
    CharBuff buff;
    if (!numberToCLocale(str, number_options, &buff)) {
        if (ok != nullptr)
            *ok = false;
        return 0;
    }

    return bytearrayToLongLong(buff.constData(), base, ok);
}
//bytearrayToLongLong
qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)
{
    bool _ok;
    const char *endptr;

    if (*num == '\0') {
        if (ok != nullptr)
            *ok = false;
        return 0;
    }

    qlonglong l = qstrtoll(num, &endptr, base, &_ok);

    if (!_ok) {
        if (ok != nullptr)
            *ok = false;
        return 0;
    }

    if (*endptr != '\0') {
        while (ascii_isspace(*endptr))
            ++endptr;
    }

    if (*endptr != '\0') {
        // we stopped at a non-digit character after converting some digits
        if (ok != nullptr)
            *ok = false;
        return 0;
    }

    if (ok != nullptr)
        *ok = true;
    return l;
}
//qstrtoll
long long
qstrtoll(const char * nptr, const char **endptr, int base, bool *ok)
{
    *ok = true;
    errno = 0;
    char *endptr2 = 0;
    long long result = qt_strtoll(nptr, &endptr2, base);
    if (endptr)
        *endptr = endptr2;
    if ((result == 0 || result == std::numeric_limits::min()
         || result == std::numeric_limits::max())
            && (errno || nptr == endptr2)) {
        *ok = false;
        return 0;
    }
    return result;
}
//qt_strtoll
/*
 * Convert a string to a long long integer.
 *
 * Assumes that the upper and lower case
 * alphabets and digits are each contiguous.
 */
long long
qt_strtoll(const char * nptr, char **endptr, int base)
{
	const char *s;
	unsigned long long acc;
	char c;
	unsigned long long cutoff;
	int neg, any, cutlim;

	/*
	 * Skip white space and pick up leading +/- sign if any.
	 * If base is 0, allow 0x for hex and 0 for octal, else
	 * assume decimal; if base is already 16, allow 0x.
	 */
	s = nptr;
	do {
		c = *s++;
	} while (ascii_isspace(c));
	if (c == '-') {
		neg = 1;
		c = *s++;
	} else {
		neg = 0;
		if (c == '+')
			c = *s++;
	}
	if ((base == 0 || base == 16) &&
	    c == '0' && (*s == 'x' || *s == 'X') &&
	    ((s[1] >= '0' && s[1] <= '9') ||
	    (s[1] >= 'A' && s[1] <= 'F') ||
	    (s[1] >= 'a' && s[1] <= 'f'))) {
		c = s[1];
		s += 2;
		base = 16;
	}
	if (base == 0)
		base = c == '0' ? 8 : 10;
	acc = any = 0;
	if (base < 2 || base > 36)
		goto noconv;

	/*
	 * Compute the cutoff value between legal numbers and illegal
	 * numbers.  That is the largest legal value, divided by the
	 * base.  An input number that is greater than this value, if
	 * followed by a legal input character, is too big.  One that
	 * is equal to this value may be valid or not; the limit
	 * between valid and invalid numbers is then based on the last
	 * digit.  For instance, if the range for quads is
	 * [-9223372036854775808..9223372036854775807] and the input base
	 * is 10, cutoff will be set to 922337203685477580 and cutlim to
	 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
	 * accumulated a value > 922337203685477580, or equal but the
	 * next digit is > 7 (or 8), the number is too big, and we will
	 * return a range error.
	 *
	 * Set 'any' if any `digits' consumed; make it negative to indicate
	 * overflow.
	 */
	cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX
	    : LLONG_MAX;
	cutlim = cutoff % base;
	cutoff /= base;
	for ( ; ; c = *s++) {
		if (c >= '0' && c <= '9')
			c -= '0';
		else if (c >= 'A' && c <= 'Z')
			c -= 'A' - 10;
		else if (c >= 'a' && c <= 'z')
			c -= 'a' - 10;
		else
			break;
		if (c >= base)
			break;
		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
			any = -1;
		else {
			any = 1;
			acc *= base;
			acc += c;
		}
	}
	if (any < 0) {
		acc = neg ? LLONG_MIN : LLONG_MAX;
		errno = ERANGE;
	} else if (!any) {
noconv:
		errno = EINVAL;
	} else if (neg)
		acc = (unsigned long long) -(long long)acc;
	if (endptr != NULL)
                *endptr = const_cast(any ? s - 1 : nptr);
	return (acc);
}

从后往前分析

(1)qt_strtoll()
// 这是一个将字符串转换为长整数的函数,它接受三个参数:  
// 1. 一个指向要转换的字符串的指针 nptr。  
// 2. 一个指向字符的指针 endptr,如果转换成功,endptr 将被设置为字符串中第一个无法被转换的字符的位置。  
// 3. 一个整数 base,用于指定数字的基数,例如十进制、十六进制等。  
long long qt_strtoll(const char * nptr, char **endptr, int base) {  

     const char *s;  // s 用于保存字符串的当前位置  
     unsigned long long acc;  // acc 用于保存累积的转换结果  
     char c;  // c 用于保存当前字符  
     unsigned long long cutoff;  // cutoff 用于保存转换的上限(基于正负和基数)  
     int neg, any, cutlim;  // neg 用于标记数字是否为负数,any 用于标记是否有字符被成功转换,cutlim 用于保存累积的上限(基于基数)  
  
 // 跳过前导空格并获取可能存在的正负号  
 // 如果 base 为 0,允许使用 '0x' 表示十六进制,'0' 表示八进制,否则默认为十进制;如果 base 已经为 16,允许使用 '0x'。  
 // (以上注释内容是针对原文代码的逐行注释,所以这里不再翻译成英文)  
 // 此处通过一个 do-while 循环来跳过前导空格  
 // c 是当前的字符,通过递增 s 来获取下一个字符  
     s = nptr;  // 设置 s 为字符串的起始位置  
     do {  
         c = *s++;  // 获取下一个字符并递增 s  
     } while (ascii_isspace(c));  // 当 c 是空格字符时继续循环  
  
 // 如果 c 是 '-',设置 neg 为 1,并将 c 设置为下一个字符  
 // 如果 c 是 '+',设置 neg 为 0,并将 c 设置为下一个字符  
     if (c == '-') {  
         neg = 1;  // 设置 neg 为 1  
         c = *s++;  // 设置 c 为下一个字符并递增 s  
     } else {  
         neg = 0;  // 设置 neg 为 0  
         if (c == '+')   // 如果 c 是 '+',则设置 c 为下一个字符并递增 s  
             c = *s++;  // 设置 c 为下一个字符并递增 s  
     }  
 
  
 // 如果 c 是 '0',并且接下来的字符是 'x' 或 'X',并且接下来的字符是十六进制数字(0-9, A-F 或 a-f),则将 base 设置为 16,并设置 c 为接下来的字符并递增 s。  
     if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X') && ((s[1] >= '0' && s[1] <= '9') || (s[1] >= 'A' && s[1] <= 'F') || (s[1] >= 'a' && s[1] <= 'f'))) {  
         c = s[1];  // 设置 c 为接下来的字符并递增 s  
         s += 2;  // 将 s 向前移动两个位置(跳过 '0x' 或 '0X')  
         base = 16;  // 设置 base 为 16  
     }
// 如果 base 是 0,则根据 c 的值将 base 设置回十进制。如果 c 是 '0',则将 base 设置回八进制;否则将 base 设置回十进制。  
     if (base == 0) {  // 如果 base 是 0,则进行以下判断来设置 base 的值  
         base = (c == '0') ? 8 : 10;  // 如果 c 是 '0',则将 base 设置回八进制;否则将 base 设置回十进制。同时设置 c 为接下来的字符并递增 s。  
     } 
    acc = 0; // 设置累积结果为0
    any = 0; // 设置任何字符被成功转换的标志为0
    cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX : LLONG_MAX; // 设置转换的上下限为正负的最大值
    cutlim = cutoff % base; // 计算转换的上下限除以基数的结果
    cutoff /= base; // 将转换的上下限除以基数得到新的上限
// 根据标志判断是否发生了溢出,如果溢出,则将累积结果设置为相应的最小值或最大值,并设置errno为ERANGE
    if (any < 0) {
        acc = neg ? LLONG_MIN : LLONG_MAX; // 设置累积结果为正负的最大值
        errno = ERANGE; // 设置errno为ERANGE,表示溢出
    } else if (!any) { // 如果没有任何字符被成功转换,则设置errno为EINVAL
        errno = EINVAL; // 设置errno为EINVAL,表示无效的输入
    } 
(2) qstrtoll()
long long qstrtoll(const char * nptr, const char **endptr, int base, bool *ok)  
// 定义一个名为qstrtoll的函数,该函数将一个字符串转换为长整数。参数包括:要转换的字符串nptr,结束字符的指针endptr,转换的进制base,和一个指向布尔值的指针ok。  
  
{  
    *ok = true;  // 初始化ok为true,表示转换过程开始时没有错误。  
    errno = 0;  // 初始化errno为0,用于记录可能发生的错误。  
    char *endptr2 = 0;  // 定义一个新的字符指针endptr2并将其初始化为0。它用于存储转换结束的位置。  
    long long result = qt_strtoll(nptr, &endptr2, base);  // 调用qt_strtoll函数进行实际的转换操作。将转换结果存储在result变量中,并将结束位置的指针存储在endptr2中。  
  
    if (endptr)  // 检查endptr是否为非空指针。如果是,则执行下面的代码块。  
        *endptr = endptr2;  // 将endptr指向的位置设置为转换结束的位置。  
  
    if ((result == 0 || result == std::numeric_limits::min()  // 检查result是否为0或者等于long long的最小值。如果是,则执行下面的代码块。  
         || result == std::numeric_limits::max())  // 或者等于long long的最大值。如果是,则执行下面的代码块。  
            && (errno || nptr == endptr2)) {  // 检查errno是否为非零值或者nptr是否等于endptr2。如果是,则执行下面的代码块。  
        *ok = false;  // 将ok设置为false,表示发生了错误。  
        return 0;  // 返回0,表示转换失败。  
    }  
    return result;  // 返回转换结果result。  
}
(3)bytearrayToLongLong()
// qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)  
// 定义一个名为bytearrayToLongLong的成员函数,该函数属于QLocaleData类,用于将字符数组转换为长整型数。  
// 输入参数包括:一个指向字符数组的指针num,表示要转换的字符串;一个int型的base,表示转换的进制;一个指向布尔值的指针ok,用于返回转换是否成功的信息。  
  
{  
    // 定义一个局部布尔变量_ok,用于存储转换是否成功的信息。  
    bool _ok;  
    // 定义一个指向字符的指针endptr,用于存储转换结束的位置。  
    const char *endptr;  
    // 检查输入的字符串是否为空,如果为空则返回错误。  
    if (*num == '\0') {  
        // 如果ok不为空,则将其设置为false并返回0。  
        if (ok != nullptr)  
            *ok = false;  
        // 返回0,表示转换失败。  
        return 0;  
    }  
    // 调用qstrtoll函数将字符串转换为长整型数,并将转换结果存储在l中,转换结束的位置存储在endptr中,转换的结果存储在_ok中。  
    qlonglong l = qstrtoll(num, &endptr, base, &_ok);  
    // 如果转换失败,则返回错误。  
    if (!_ok) {  
        // 如果ok不为空,则将其设置为false并返回0。  
        if (ok != nullptr)  
            *ok = false;  
        // 返回0,表示转换失败。  
        return 0;  
    }  
    // 检查转换结束的位置是否为字符串的末尾,如果不是,则跳过之后的空白字符。  
    if (*endptr != '\0') {  
        while (ascii_isspace(*endptr))  
            ++endptr;  
    }  
    // 如果转换结束的位置不是字符串的末尾,说明在转换完一些数字之后遇到了非数字字符。  
    if (*endptr != '\0') {  
        // 在转换了一些数字之后遇到了一个非数字字符,设置ok为false并返回错误。  
        // we stopped at a non-digit character after converting some digits  
        if (ok != nullptr)  
            *ok = false;  
        // 返回0,表示转换失败。  
        return 0;  
    }  
    // 设置ok为true,表示转换成功。  
    if (ok != nullptr)  
        *ok = true;  
    // 返回转换结果。  
    return l;  
}
(4)toIntegral_helper
// T toIntegral_helper(const QChar *data, int len, bool *ok, int base) 函数接受四个参数:  
// 1. const QChar *data: 一个指向字符数据的指针,这些数据应该是要转换的数字字符串。  
// 2. int len: 字符数据的长度。  
// 3. bool *ok: 一个指向布尔值的指针,用于指示转换是否成功。如果转换成功,它将设置为true,否则设置为false。  
// 4. int base: 转换的基数,例如十进制、十六进制等。  
  
{  
    // ### Qt6: use std::conditional::value, qulonglong, qlonglong>::type  
    // 在Qt6中,建议使用std::conditional来选择正确的类型。如果T是无符号整数类型,选择qulonglong,否则选择qlonglong。  
    const bool isUnsigned = T(0) < T(-1); // 判断T是否是无符号整数类型,如果是,isUnsigned为true,否则为false。  
  
    // 使用std::conditional来选择正确的类型。如果是无符号整数,选择qulonglong,否则选择qlonglong。  
    typedef typename QtPrivate::QConditional::Type Int64;   
  
    // 使用std::conditional来选择正确的类型。如果是无符号整数,选择uint,否则选择int。  
    typedef typename QtPrivate::QConditional::Type Int32;  
  
    // 通过将len强制转换为Int32来选择正确的重载函数。这允许我们处理int和uint两种情况。  
    // we select the right overload by casting size() to int or uint 
    // toIntegral_helper为另一个重载函数
    Int64 val = toIntegral_helper(data, Int32(len), ok, base);  
  
    // 检查转换后的值是否溢出。如果溢出,我们将ok设置为false,并将val设置为0。  
    if (T(val) != val) {  
        if (ok)  
            *ok = false;  
        val = 0;  
    }  
    return T(val); // 返回转换后的值。  
}
2 static QString number(int, int base=10);
(1)源码
QString QString::number(int n, int base)
{
    return number(qlonglong(n), base);
}
//number()
QString QString::number(qlonglong n, int base)
{
#if defined(QT_CHECK_RANGE)
    if (base < 2 || base > 36) {
        qWarning("QString::setNum: Invalid base (%d)", base);
        base = 10;
    }
#endif
    return QLocaleData::c()->longLongToString(n, -1, base);
}
//longLongToString
QString QLocaleData::longLongToString(qlonglong l, int precision,
                                            int base, int width,
                                            unsigned flags) const
{
    return longLongToString(m_zero, m_group, m_plus, m_minus,
                                            l, precision, base, width, flags);
}
QString QLocaleData::longLongToString(const QChar zero, const QChar group,
                                         const QChar plus, const QChar minus,
                                         qlonglong l, int precision,
                                         int base, int width,
                                         unsigned flags)
{
    bool precision_not_specified = false;
    if (precision == -1) {
        precision_not_specified = true;
        precision = 1;
    }

    bool negative = l < 0;
    if (base != 10) {
        // these are not supported by sprintf for octal and hex
        flags &= ~AlwaysShowSign;
        flags &= ~BlankBeforePositive;
        negative = false; // neither are negative numbers
    }

QT_WARNING_PUSH
    /* "unary minus operator applied to unsigned type, result still unsigned" */
QT_WARNING_DISABLE_MSVC(4146)
    /*
      Negating std::numeric_limits::min() hits undefined behavior, so
      taking an absolute value has to cast to unsigned to change sign.
     */
    QString num_str = qulltoa(negative ? -qulonglong(l) : qulonglong(l), base, zero);
QT_WARNING_POP

    uint cnt_thousand_sep = 0;
    if (flags & ThousandsGroup && base == 10) {
        for (int i = num_str.length() - 3; i > 0; i -= 3) {
            num_str.insert(i, group);
            ++cnt_thousand_sep;
        }
    }

    for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)
        num_str.prepend(base == 10 ? zero : QChar::fromLatin1('0'));

    if ((flags & ShowBase)
            && base == 8
            && (num_str.isEmpty() || num_str[0].unicode() != QLatin1Char('0')))
        num_str.prepend(QLatin1Char('0'));

    // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
    // when precision is not specified in the format string
    bool zero_padded = flags & ZeroPadded
                        && !(flags & LeftAdjusted)
                        && precision_not_specified;

    if (zero_padded) {
        int num_pad_chars = width - num_str.length();

        // leave space for the sign
        if (negative
                || flags & AlwaysShowSign
                || flags & BlankBeforePositive)
            --num_pad_chars;

        // leave space for optional '0x' in hex form
        if (base == 16 && (flags & ShowBase))
            num_pad_chars -= 2;
        // leave space for optional '0b' in binary form
        else if (base == 2 && (flags & ShowBase))
            num_pad_chars -= 2;

        for (int i = 0; i < num_pad_chars; ++i)
            num_str.prepend(base == 10 ? zero : QChar::fromLatin1('0'));
    }

    if (flags & CapitalEorX)
        num_str = std::move(num_str).toUpper();

    if (base == 16 && (flags & ShowBase))
        num_str.prepend(QLatin1String(flags & UppercaseBase ? "0X" : "0x"));
    if (base == 2 && (flags & ShowBase))
        num_str.prepend(QLatin1String(flags & UppercaseBase ? "0B" : "0b"));

    // add sign
    if (negative)
        num_str.prepend(minus);
    else if (flags & AlwaysShowSign)
        num_str.prepend(plus);
    else if (flags & BlankBeforePositive)
        num_str.prepend(QLatin1Char(' '));

    return num_str;
}
(2)QString longLongToString() const;
QString QLocaleData::longLongToString(const QChar zero, const QChar group,const QChar plus,const QChar minus, qlonglong l, int precision,int base, int width, unsigned flags)  
{  
    // 判断精度是否未指定  
    bool precision_not_specified = false;  
    if (precision == -1) {  
        precision_not_specified = true;  
        precision = 1;  
    }  
    // 判断数值是否为负数  
    bool negative = l < 0;  
    if (base != 10) {  
        // 当进制不为10时,以下标志将被禁用:始终显示符号,以及在正数前空格对齐  
        // these are not supported by sprintf for octal and hex  
        flags &= ~AlwaysShowSign;  
        flags &= ~BlankBeforePositive;  
        negative = false; // 负数也不支持  
    }  
// 此处使用了QT的警告控制宏,禁用MSVC的4146警告,该警告通常表示有未使用的变量  
QT_WARNING_PUSH  
QT_WARNING_DISABLE_MSVC(4146)  
    // 使用qulltoa函数将长整型数值转换为字符串,参数包括是否为负数、进制、零字符  
    QString num_str = qulltoa(negative ? -qulonglong(l) : qulonglong(l), base, zero);  
QT_WARNING_POP  
    uint cnt_thousand_sep = 0;  
    // 如果设置了千位分隔标志并且进制为10,则对字符串进行千位分隔  
    if (flags & ThousandsGroup && base == 10) {  
        for (int i = num_str.length() - 3; i > 0; i -= 3) {  
            num_str.insert(i, group);  
            ++cnt_thousand_sep;  
        }  
    }  
    // 如果精度不够,则在前面补零  
    for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)  
        num_str.prepend(base == 10 ? zero : QChar::fromLatin1('0'));  
    // 如果设置了显示基数的标志,并且进制为8,并且字符串为空或者第一个字符不是'0',则在前面添加'0'  
    if ((flags & ShowBase)  
            && base == 8  
            && (num_str.isEmpty() || num_str[0].unicode() != QLatin1Char('0')))  
        num_str.prepend(QLatin1Char('0'));  
    // 判断是否需要零填充,并且没有左对齐标志,并且精度未指定  
    bool zero_padded = flags & ZeroPadded  
                        && !(flags & LeftAdjusted)  
                        && precision_not_specified;  
    //如果zero_padded为true,则计算需要在数字字符串前填充的零的数量。同时,如果需要,还会为负号、正号留出空间,以及在十六进制或二进制显示时,为基数标志留出空间。之后,它循环填充零,然后返回格式化的字符串。
    if (zero_padded) {
        int num_pad_chars = width - num_str.length();

        // leave space for the sign
        if (negative
                || flags & AlwaysShowSign
                || flags & BlankBeforePositive)
            --num_pad_chars;

        // leave space for optional '0x' in hex form
        if (base == 16 && (flags & ShowBase))
            num_pad_chars -= 2;
        // leave space for optional '0b' in binary form
        else if (base == 2 && (flags & ShowBase))
            num_pad_chars -= 2;

        for (int i = 0; i < num_pad_chars; ++i)
            num_str.prepend(base == 10 ? zero : QChar::fromLatin1('0'));
    }
    //如果设置了CapitalEorX标志,会将数字字符串转换为大写。
    if (flags & CapitalEorX)
        num_str = std::move(num_str).toUpper();
    //如果进制为16且显示基数的标志被设置,会在数字字符串前添加0x或0X。
    //如果进制为2且显示基数的标志被设置,会在数字字符串前添加0b或0B。
    if (base == 16 && (flags & ShowBase))
        num_str.prepend(QLatin1String(flags & UppercaseBase ? "0X" : "0x"));
    if (base == 2 && (flags & ShowBase))
        num_str.prepend(QLatin1String(flags & UppercaseBase ? "0B" : "0b"));
    //最后,如果数字是负数,会在字符串前添加负号;如果设置了始终显示符号的标志,会在字符串前添加正号;如果设置了空格在正数前的标志,会在字符串前添加空格。
    // add sign
    if (negative)
        num_str.prepend(minus);
    else if (flags & AlwaysShowSign)
        num_str.prepend(plus);
    else if (flags & BlankBeforePositive)
        num_str.prepend(QLatin1Char(' '));

    return num_str;
}
    
(3)QString qulltoa(qulonglong l, int base, const QChar _zero);
//这段代码的主要功能是将一个qulonglong类型的整数转化为指定基数的字符串形式。其中处理了两种特殊情况:当基数不为10或者_zero字符为'0'时,会使用数字0到9来表示余数;否则会使用_zero字符加上余数的值来表示余数。
// 定义一个函数,将qulonglong类型的数转化为字符串,基数在10-36之间,使用QChar类型的_zero字符来表示零  
QString qulltoa(qulonglong l, int base, const QChar _zero)  
  
// 定义一个长度为65的ushort数组,用于存储整数l被基数除后的余数,最多可以表示65位的数(对于uint64_t类型来说)  
ushort buff[65]; // length of MAX_ULLONG in base 2  
  
// 定义一个指向buff数组的指针p,初始化为数组末尾的地址  
ushort *p = buff + 65;  
  
// 如果基数不为10,或者_zero字符的unicode值为'0',则执行下面的循环  
if (base != 10 || _zero.unicode() == '0') {  
    // 循环直到整数l为0  
    while (l != 0) {  
        // 计算l除以基数的余数  
        int c = l % base;  
  
        // 将指针p减1,因为我们将向数组的头部填充数据  
        --p;  
  
        // 如果余数小于10,则将其转化为字符'0'到'9',并存储在指针p指向的地址  
        if (c < 10)  
            *p = '0' + c;  
        // 如果余数大于等于10,则将其转化为字符'a'到'z',并存储在指针p指向的地址  
        else  
            *p = c - 10 + 'a';  
  
        // 计算l除以基数的商,更新l的值  
        l /= base;  
    }  
}  
// 如果基数为10,且_zero字符的unicode值不为'0',则执行下面的循环  
else {  
    // 循环直到整数l为0  
    while (l != 0) {  
        // 计算l除以基数的余数  
        int c = l % base;  
  
        // 将余数加上_zero的unicode值,得到对应的字符,并存储在指针p指向的地址,然后将指针p减1  
        *(--p) = _zero.unicode() + c;  
  
        // 计算l除以基数的商,更新l的值  
        l /= base;  
    }  
}  
  
// 将数组buff中的数据(存储在p指向的地址到buff数组末尾)转化为QString类型并返回,数组的长度为65减去指针p和数组buff的差值(即p-buff)  
return QString(reinterpret_cast(p), 65 - (p - buff));

你可能感兴趣的:(QT,Qt源码学习,qt,开发语言)