一、下载地址

如果你不想知道步骤,只想下载源码,这是2021-08-01发布的glibc-3.24的下载地址:

https://ftp.gnu.org/gnu/libc/glibc-2.34.tar.gz

二、怎么知道从哪里下载

  1. stackoverflow上有一个问题:Where can I find the source code for all the C standard libraries?,其中有一个答案提到了glibc官网。

  2. 在glibc官网页面点这里:

  3. 在详情页面搜索download

  4. 来到了gnu的ftp服务器,然后按版本号或年份去找对应的版本,比如2011年的在这里,点击就可以下载了:

三、C本身的源码对学习C语言有帮助吗

3.1 我的答案是:帮助不大

在上面的stackoverflow的答案中有这么一句话,意思是:所有人都建议你不要去看C语言的具体实现。(前人走弯路的经验啊)

我没信这个邪,偏要去下载。然后我看到:

3.2 printf源码

printf方法定义在glibc-2.34/stdio-common/printf.c文件中,代码如下:

int
__printf (const char *format, ...)
{va_list arg;int done;va_start (arg, format);done = __vfprintf_internal (stdout, format, arg, 0);va_end (arg);return done;
}

里面调用了__vfprintf_internal方法

3.3 __vfprintf_internal的源码

__vfprintf_internal方法定义在glibc-2.34/stdio-common/vfprintf-internal.c文件中,__vfprintf_internalvfprintf方法的别名(# define vfprintf __vfprintf_internal),vfprintf方法的代码如下(我已经看不懂这段300多行的代码了):

int
vfprintf (FILE *s, const CHAR_T *format, va_list ap, unsigned int mode_flags)
{/* The character used as thousands separator.  */THOUSANDS_SEP_T thousands_sep = 0;/* The string describing the size of groups of digits.  */const char *grouping;/* Place to accumulate the result.  */int done;/* Current character in format string.  */const UCHAR_T *f;/* End of leading constant string.  */const UCHAR_T *lead_str_end;/* Points to next format specifier.  */const UCHAR_T *end_of_spec;/* Buffer intermediate results.  */CHAR_T work_buffer[WORK_BUFFER_SIZE];CHAR_T *workend;/* We have to save the original argument pointer.  */va_list ap_save;/* Count number of specifiers we already processed.  */int nspecs_done;/* For the %m format we may need the current `errno' value.  */int save_errno = errno;/* 1 if format is in read-only memory, -1 if it is in writable memory,0 if unknown.  */int readonly_format = 0;/* Orient the stream.  */
#ifdef ORIENTORIENT;
#endif/* Sanity check of arguments.  */ARGCHECK (s, format);#ifdef ORIENT/* Check for correct orientation.  */if (_IO_vtable_offset (s) == 0&& _IO_fwide (s, sizeof (CHAR_T) == 1 ? -1 : 1)!= (sizeof (CHAR_T) == 1 ? -1 : 1))/* The stream is already oriented otherwise.  */return EOF;
#endifif (UNBUFFERED_P (s))/* Use a helper function which will allocate a local temporary bufferfor the stream and then call us again.  */return buffered_vfprintf (s, format, ap, mode_flags);/* Initialize local variables.  */done = 0;grouping = (const char *) -1;
#ifdef __va_copy/* This macro will be available soon in gcc's <stdarg.h>.  We need itsince on some systems `va_list' is not an integral type.  */__va_copy (ap_save, ap);
#elseap_save = ap;
#endifnspecs_done = 0;#ifdef COMPILE_WPRINTF/* Find the first format specifier.  */f = lead_str_end = __find_specwc ((const UCHAR_T *) format);
#else/* Find the first format specifier.  */f = lead_str_end = __find_specmb ((const UCHAR_T *) format);
#endif/* Lock stream.  */_IO_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, s);_IO_flockfile (s);/* Write the literal text before the first format.  */outstring ((const UCHAR_T *) format,lead_str_end - (const UCHAR_T *) format);/* If we only have to print a simple string, return now.  */if (*f == L_('\0'))goto all_done;/* Use the slow path in case any printf handler is registered.  */if (__glibc_unlikely (__printf_function_table != NULL|| __printf_modifier_table != NULL|| __printf_va_arg_table != NULL))goto do_positional;/* Process whole format string.  */do{STEP0_3_TABLE;STEP4_TABLE;union printf_arg *args_value;    /* This is not used here but ... */int is_negative; /* Flag for negative number.  */union{unsigned long long int longlong;unsigned long int word;} number;int base;union printf_arg the_arg;CHAR_T *string; /* Pointer to argument string.  */int alt = 0; /* Alternate format.  */int space = 0; /* Use space prefix if no sign is needed.  */int left = 0; /* Left-justify output.  */int showsign = 0;   /* Always begin with plus or minus sign.  */int group = 0; /* Print numbers according grouping rules.  */int is_long_double = 0; /* Argument is long double/ long long int.  */int is_short = 0; /* Argument is short int.  */int is_long = 0;  /* Argument is long int.  */int is_char = 0;   /* Argument is promoted (unsigned) char.  */int width = 0; /* Width of output; 0 means none specified.  */int prec = -1;  /* Precision of output; -1 means none specified.  *//* This flag is set by the 'I' modifier and selects the use of the`outdigits' as determined by the current locale.  */int use_outdigits = 0;UCHAR_T pad = L_(' ');/* Padding character.  */CHAR_T spec;workend = work_buffer + WORK_BUFFER_SIZE;/* Get current character in format string.  */JUMP (*++f, step0_jumps);/* ' ' flag.  */LABEL (flag_space):space = 1;JUMP (*++f, step0_jumps);/* '+' flag.  */LABEL (flag_plus):showsign = 1;JUMP (*++f, step0_jumps);/* The '-' flag.  */LABEL (flag_minus):left = 1;pad = L_(' ');JUMP (*++f, step0_jumps);/* The '#' flag.  */LABEL (flag_hash):alt = 1;JUMP (*++f, step0_jumps);/* The '0' flag.  */LABEL (flag_zero):if (!left)pad = L_('0');JUMP (*++f, step0_jumps);/* The '\'' flag.  */LABEL (flag_quote):group = 1;if (grouping == (const char *) -1){#ifdef COMPILE_WPRINTFthousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,_NL_NUMERIC_THOUSANDS_SEP_WC);
#elsethousands_sep = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
#endifgrouping = _NL_CURRENT (LC_NUMERIC, GROUPING);if (*grouping == '\0' || *grouping == CHAR_MAX
#ifdef COMPILE_WPRINTF|| thousands_sep == L'\0'
#else|| *thousands_sep == '\0'
#endif)grouping = NULL;}JUMP (*++f, step0_jumps);LABEL (flag_i18n):use_outdigits = 1;JUMP (*++f, step0_jumps);/* Get width from argument.  */LABEL (width_asterics):{const UCHAR_T *tmp;  /* Temporary value.  */tmp = ++f;if (ISDIGIT (*tmp)){int pos = read_int (&tmp);if (pos == -1){__set_errno (EOVERFLOW);done = -1;goto all_done;}if (pos && *tmp == L_('$'))/* The width comes from a positional parameter.  */goto do_positional;}width = va_arg (ap, int);/* Negative width means left justified.  */if (width < 0){width = -width;pad = L_(' ');left = 1;}}JUMP (*f, step1_jumps);/* Given width in format string.  */LABEL (width):width = read_int (&f);if (__glibc_unlikely (width == -1)){__set_errno (EOVERFLOW);done = -1;goto all_done;}if (*f == L_('$'))/* Oh, oh.  The argument comes from a positional parameter.  */goto do_positional;JUMP (*f, step1_jumps);LABEL (precision):++f;if (*f == L_('*')){const UCHAR_T *tmp;   /* Temporary value.  */tmp = ++f;if (ISDIGIT (*tmp)){int pos = read_int (&tmp);if (pos == -1){__set_errno (EOVERFLOW);done = -1;goto all_done;}if (pos && *tmp == L_('$'))/* The precision comes from a positional parameter.  */goto do_positional;}prec = va_arg (ap, int);/* If the precision is negative the precision is omitted.  */if (prec < 0)prec = -1;}else if (ISDIGIT (*f)){prec = read_int (&f);/* The precision was specified in this case as an extremelylarge positive value.  */if (prec == -1){__set_errno (EOVERFLOW);done = -1;goto all_done;}}elseprec = 0;JUMP (*f, step2_jumps);/* Process 'h' modifier.  There might another 'h' following.  */LABEL (mod_half):is_short = 1;JUMP (*++f, step3a_jumps);/* Process 'hh' modifier.  */LABEL (mod_halfhalf):is_short = 0;is_char = 1;JUMP (*++f, step4_jumps);/* Process 'l' modifier.  There might another 'l' following.  */LABEL (mod_long):is_long = 1;JUMP (*++f, step3b_jumps);/* Process 'L', 'q', or 'll' modifier.  No other modifier isallowed to follow.  */LABEL (mod_longlong):is_long_double = 1;is_long = 1;JUMP (*++f, step4_jumps);LABEL (mod_size_t):is_long_double = sizeof (size_t) > sizeof (unsigned long int);is_long = sizeof (size_t) > sizeof (unsigned int);JUMP (*++f, step4_jumps);LABEL (mod_ptrdiff_t):is_long_double = sizeof (ptrdiff_t) > sizeof (unsigned long int);is_long = sizeof (ptrdiff_t) > sizeof (unsigned int);JUMP (*++f, step4_jumps);LABEL (mod_intmax_t):is_long_double = sizeof (intmax_t) > sizeof (unsigned long int);is_long = sizeof (intmax_t) > sizeof (unsigned int);JUMP (*++f, step4_jumps);/* Process current format.  */while (1){process_arg (((struct printf_spec *) NULL));process_string_arg (((struct printf_spec *) NULL));LABEL (form_unknown):if (spec == L_('\0')){/* The format string ended before the specifier is complete.  */__set_errno (EINVAL);done = -1;goto all_done;}/* If we are in the fast loop force entering the complicatedone.  */goto do_positional;}/* The format is correctly handled.  */++nspecs_done;/* Look for next format specifier.  */
#ifdef COMPILE_WPRINTFf = __find_specwc ((end_of_spec = ++f));
#elsef = __find_specmb ((end_of_spec = ++f));
#endif/* Write the following constant string.  */outstring (end_of_spec, f - end_of_spec);}while (*f != L_('\0'));/* Unlock stream and return.  */goto all_done;/* Hand off processing for positional parameters.  */
do_positional:done = printf_positional (s, format, readonly_format, ap, &ap_save,done, nspecs_done, lead_str_end, work_buffer,save_errno, grouping, thousands_sep, mode_flags);all_done:/* Unlock the stream.  */_IO_funlockfile (s);_IO_cleanup_region_end (0);return done;
}

3.4 还有很多汇编文件

在查东西的时候还发现源码里面有大量的汇编文件,比如glibc-2.34/sysdeps/x86_64/multiarch目录下的文件:

即C文件里面又调用了汇编文件里面的方法。
我已经了解一些粗浅的C语言和汇编相关的知识了,但是看C语言源码中的C文件和汇编文件基本上还是看不懂,所以如果你不是钻研C语言源码的话,建议你直接放弃~

怎样找到C语言本身的源码(比如stdio),对学习C语言有帮助吗?相关推荐

  1. c语言远控源码,远控鼠标!C语言简单小程序:舍友要砸电脑了,送源码!

    关注<一碳科技>有更多干货等着你哦! 远控鼠标 远控鼠标,顾名思义就是远程控制鼠标,听起来就有些复杂对不对?是的,有些人一听到这个词,就会感觉要实现远控鼠标是一件很麻烦的事情,但其实不是的 ...

  2. c语言物流管理信息系统,[源码和文档分享]基于C语言的物流配送管理信息系统...

    一 需求分析 系统需要实现的功能如下: (一)各种基本数据的录入 配送路线基本信息录入 路线经停站点基本信息录入 站点经停车辆基本信息录入 其它信息录入 (二)各种基本数据的修改 即:允许对已经录入的 ...

  3. 易语言和python混合编程_易语言python交互源码,不需要把易语言编译成静态库

    .版本 2 .支持库 spec .子程序 _启动子程序, 整数型, , 本子程序在程序启动后最先执行 .局部变量 mothod, PyMethodDef .局部变量 创建结果, 整数型 .局部变量 错 ...

  4. Go 语言 bytes.Buffer 源码详解之1

    转载地址:Go 语言 bytes.Buffer 源码详解之1 - lifelmy的博客 前言 前面一篇文章 Go语言 strings.Reader 源码详解,我们对 strings 包中的 Reade ...

  5. 易语言和html交互,易语言网页交互源码

    易语言网页交互源码系统结构:浏览器消息处理函数,滚动到底部,添加文本,呼叫窗口函数地址_,设置窗口信息_,寻找子窗口_,DLL命令1, ======窗口程序集1 || ||------__启动窗口_创 ...

  6. c调用易语言串口,易语言串口API源码

    易语言串口API源码系统结构:ReadCommPure,BuildCommDCB,CreateFilea,关闭句柄a,SetCommState,ReadFileA,GetCommState,Write ...

  7. 字符串固定长度 易语言_易语言字符串操作源码

    易语言字符串操作源码 系统结构:字符串_取长度,字符串_取中间,字符串_取左边,字符串_取右边,字符串_替换,到宽字符,到多字节,取文本数据地址,取字节集数据地址,MultiByteToWideCha ...

  8. 易语言修改虚拟机硬盘id_易语言本地虚拟机源码

    易语言本地虚拟机源码 系统结构:显示工具路径,读入未用分区,获取分区位置,设置虚拟机分区,读入虚拟分区,操作并显示日志,处理显示错误提示,取驱动器文本列表,写配置目录,处理结果文件,格式化时间,取Do ...

  9. 易语言模拟器中控源码 全新手游模拟器通用中控源码, 适用于各种游戏, 源码现成的只需要更换游戏就可以用哦

    易语言模拟器中控源码 全新手游模拟器通用中控源码, 适用于各种游戏, 源码现成的只需要更换游戏就可以用哦, 带修改教程,带讲解说明, 简单易懂不需要别人指导在家可以自学. 降低新手编写多线程中控的门槛 ...

最新文章

  1. linux下各种格式的压缩包的压缩、解压方法
  2. 【深度学习】transformer 真的快要取代计算机视觉中的 CNN 吗?
  3. c语言实现循环单链表
  4. android5.1 显示方向,Android5.1 Settings.apk定制显示选项
  5. android中常见的错误及解决办法
  6. python课堂笔记之django-day02(7)
  7. 苹果公司官方证实,iPhone12延期!
  8. 人人都应该学习并成为优秀的产品经理,因为你要为《你自己》这个产品负责到底
  9. 吉林大学计算机学院刘衍衍教授,周柚-吉林大学计算机科学与技术学院
  10. 基于ssm的空气质量监测系统
  11. Python+Selenium爬虫实现:草料二维码微信群活码自动更新,提升社群运营效率
  12. Win10 ipv6无网络访问权限怎么解决
  13. cousera上的华盛顿机器学习专项课程的案例学习学习经历分享
  14. 全网最详细最基础的网络安全入门教程
  15. IO流_IO流小结图解
  16. L5W2作业1 Emojify!
  17. 苹果微信验证失败,安卓成功_苹果将​​在微软失败的地方成功吗?
  18. 芝加哥德保大学计算机排名怎么样,伊利诺伊大学芝加哥分校计算机科学computer science专业排名第201~250名(2020THE泰晤士高等教育世界大学排名)...
  19. 优质供应商选择标准_供应商选择原则
  20. 乔布斯《遗失的访谈》全文:尘封16年的预见

热门文章

  1. 调用淘宝接口有每IP数量/时间限制-负载均衡解决
  2. AngularJS中多种过滤器的使用
  3. USACO fact4, spin
  4. 通过unix时间戳获得两个时间相差多少自然日
  5. GPRS智能净水器方案
  6. MSCOCO数据集下载安装---image_caption
  7. stack expects each tensor to be equal size, but got [3, 40, 160] at entry 0 and [4, 40, 160] at entr
  8. Navicat 连接 sqlserver 带端口号配置
  9. python字典格式 城市和行政编码映射表(无序)
  10. Android ImageView 选中状态