大写如何工作?

时间:2014-04-30 18:21:41

标签: ruby ruby-c-extension

我试图了解String#capitalize!内部如何运作。我可以创建一个哈希。给定字符串foo = "the"foo[0]"t",查找lower_case "t",并将其与大写"T"值匹配。事实上,Ruby源代码显示:

static VALUE
rb_str_capitalize_bang(VALUE str)
{
    rb_encoding *enc;
    char *s, *send;
    int modify = 0;
    unsigned int c;
    int n;

    str_modify_keep_cr(str);
    enc = STR_ENC_GET(str);
    rb_str_check_dummy_enc(enc);
    if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return Qnil;
    s = RSTRING_PTR(str); send = RSTRING_END(str);

    c = rb_enc_codepoint_len(s, send, &n, enc);
    if (rb_enc_islower(c, enc)) {
        rb_enc_mbcput(rb_enc_toupper(c, enc), s, enc);
        modify = 1;
    }
    s += n;
    while (s < send) {
        c = rb_enc_codepoint_len(s, send, &n, enc);
        if (rb_enc_isupper(c, enc)) {
            rb_enc_mbcput(rb_enc_tolower(c, enc), s, enc);
            modify = 1;
        }
        s += n;
    }

    if (modify) return str;
    return Qnil;
}

相关功能为toupper。它如何知道toupper("t")等于"T"

3 个答案:

答案 0 :(得分:6)

你想知道它是如何知道角色的大写版本是什么的?像大多数此类函数的实际实现一样,它使用lookup table

答案 1 :(得分:1)

toupperansi C function。这意味着确切的实现实际上取决于库的提供程序,大多数情况下它是您的编译器。

有可能它遵循ASCII表,因为没有查找和整数之和一样快 - 查找中的一个步骤应该包含一个和,来计算新地址。

所以,on gcc,我们有这个实现

char
ctype<char>::do_toupper(char __c) const
{
  int __x = __c;
  return (this->is(ctype_base::lower, __c) ? (__x - 'a' + 'A') : __x);
}

这基本上会检查它是否降低。如果是,则返回较低的。否则,它会减去97然后减去65,这与减去32相同。请记住,计算机的字符和数字是相同的,只是二进制数据。然后,请注意如何使用字符代替数字以获得更好的可读性(好吧,至少对于C人来说)。

答案 2 :(得分:0)

如果不查看任何源代码,我猜想一种方法是将一个字符转换为它的字符。相应的ASCII值,从中减去32并将ASCII值转换回char。

enter image description here