Giter Site home page Giter Site logo

clang-tutorial's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clang-tutorial's Issues

字符串章节,书写错误

”C 语言允许合并多个字符串字面量“
应该为: “C 语言允许合并多个字符串字量”

内存管理章节:
“指针变量必须有类型,否则编译器无法知道,如何解读内存块保存的二进制数据。“
建议改成” 指针变量必须有类型,否则编译器不知道如何解读内存块保存的二进制数据。“

string里面好像有一处错误

string~字符串~字符串变量的声明~第二段文字中“如果采用第一种写法”,这里想表达的好像是第二种

12. struct结构一章struct的嵌套变量声明存在问题

struct breed {
  char* name;
  int kinds;
};

struct fish {
  char* name;
  int age;
--->  struct species breed;
};

实际上应为

struct breed {
  char* name;
  int kinds;
};

struct fish {
  char* name;
  int age;
  struct breed species;
};

或是

struct species {
  char* name;
  int kinds;
};

struct fish {
  char* name;
  int age;
  struct species breed;
};

9. 数组 - 4. 变长数组

数组声明的时候,数组长度除了使用常量,也可以使用变量。

有点英式写法,建议:声明数组的时候,数组长度既可以是常量,也可以是变量。

任何长度需要运行时才能确定的数组,都是变长数组。

建议:任何需要运行时才能确定长度的数组 ...

上面示例中,三个数组的长度都需要运行代码才能直到,所以它们都是变长数组。

拼写:直到⇒知道,并且建议改成:才能确定

第11章-内存管理calloc()参数说明错误

原文:

calloc()接受两个参数,第一个参数是数据类型的单位字节长度,第二个是该数据类型的数量

此处应该是反过来:

calloc()接受两个参数,第一个参数是该数据类型的数量,第二个是数据类型的单位字节长度

贴下官方的API文档:

Screen Shot 2021-10-17 at 19 25 14

右侧导航建议

WangDoc网站的文字一般挺长的,有两个建议
1、导航栏能不能随着滚动条走,总是显示在屏幕右侧,便于选择阅读,特别是再次阅读时是选读的。
2、建议加一个返回顶部的按钮小火箭,便于回到页面内导航,复习阅读。
不知是否可行
感谢阮老师的辛苦付出和无私奉献%%%STO

运算符-> 逗号运算符 运算结果有点问题

x = 1, 2, 3;
上面示例中,逗号的优先级高于赋值运算符,所以会执行。由于逗号运算符返回最后一个表达式的值,所以变量x等于3。

x = 1, 2, 3; 执行后 x 的结果是 1,逗号的优先级高于赋值运算符 这句话有误,应该是 逗号的优先级低于赋值运算符,且按从左到右的顺序运算。所以先运行 = 运算符,直接将 1 赋值给 x。

x = 1, 2, 3; 可以看作 (x = 1), 2, 3; 整个表达式的返回值是 3。

Union 联合体的解释完全错误

给联合体中的某一字段赋值并不会使之前赋值的字段失效,也不会禁止用户访问之前的字段,例如

typedef union {
  char c;
  int i;
} U;

U u = { .c = 'A' }; // u.i == 65

联合体一般在嵌入式中比较常用,用于使用不同的方式访问寄存器

typedef union {
  struct {
    unsigned char all_bits;
  };
  struct {
    unsigned char bit0 : 1;
    unsigned char bit1 : 1;
    unsigned char bit2 : 1;
    unsigned char bit3 : 1;
    unsigned char bit4 : 1;
    unsigned char bit5 : 1;
    unsigned char bit6 : 1;
    unsigned char bit7 : 1;
  };
} U;

这样就可以通过 all_bits 访问、修改整个寄存器的值,或者通过位名称访问、修改指定的位了

另外在 PyTorch 的 c10 模块中,还借助 union 实现了 BF16 数据类型

using int_repr_t = uint16_t;
using float_t = c10::BFloat16;

union {
  float_t f;
  int_repr_t i;
}

LibTorch 中,BF16、FP16 与 FP32 的转换是通过解释成无符号整形然后使用位运算实现的,如果不使用 union 的话就需要大量使用 std::bit_cast。而如果使用 union,只需对其整数字段取值、赋值即可,在使用浮点字段的时候相当于自动进行了一次 tsd::bit_cast


另外项目名中的 clang 容易与 LLVM 的 C 编译器前端 Clang 产生混淆,建议更名为 c-lang-tutorial

建议改名

教程挺好的,但是clang有歧义,为了更符合教程内容,建议改个名字

变长数组作为函数的参数,编译报错

请问这是什么情况???

书中的案例

int sum_array(int n, int a[n]) {
  // ...
}

int a[] = {3, 5, 7, 3};
int sum = sum_array(4, a);

编译报错

 error C2057: 应输入常量表达式
 error C2466: 不能分配常量大小为 0 的数组
NMAKE : fatal error U1077: “C:\PROGRA~2\MICROS~2\2017\BUILDT~1\VC\Tools\MSVC\1416~1.270\bin\Hostx86\x86\cl.exe”: 返回代码“0x2”
Stop.
NMAKE : fatal error U1077: “"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\HostX86\x86\nmake.exe"”: 返回代码“0x2”
Stop.
NMAKE : fatal error U1077: “"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\HostX86\x86\nmake.exe"”: 返回代码“0x2”
Stop.
NMAKE : fatal error U1077: “"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\HostX86\x86\nmake.exe"”: 返回代码“0x2”
Stop.

image

<-std> Standard names should to be lowercase.

https://github.com/wangdoc/clang-tutorial/blame/b0a8bf17fda3ce5da8c85bc0af9fa9d1a2e711c1/docs/intro.md#L142

root@william:~/c# gcc -std=C99 hello.c
gcc: error: unrecognized command-line option ‘-std=C99’; did you mean ‘-std=c99’?
root@william:~/c#
root@william:~/c# gcc --version
gcc (Ubuntu 10.3.0-1ubuntu1) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

root@william:~/c# gcc -std=c99 hello.c
root@william:~/c#

for循环变量的作用域问题

变量的作用域
链接文章结尾处的代码

for (int i = 0; i < 5; i++) {
  int i = 999;
  printf("%d\n", i);
}

printf("%d\n", i); // 非法

运行报错 error: redeclaration of 'int i'

image

老师想表达的是嵌套循环的作用域?

for (int i = 0; i < 5; i++)
{
    for (int i = 0; i < 3; i++)
    {
        //...
    }
}

这样是可以重复定义i变量的。
image

stdint.h 有误

C 语言标准要求至少定义以下类型。

- int8_t uint8_t
- int16_t uint16_t
- int32_t uint32_t
- int64_t uint64_t
- int_least8_t uint_least8_t
- int_least16_t uint_least16_t
- int_least32_t uint_least32_t
- int_least64_t uint_least64_t
- int_fast8_t uint_fast8_t
- int_fast16_t uint_fast16_t
- int_fast32_t uint_fast32_t
- int_fast64_t uint_fast64_t

cppreference,int8_t、int16_t、int32_t、int64_t uint8_t、uint16_t、uint32_t、uint64_t 皆为可选实现。

建议添加文档参考资料的链接

读了阮老师的ssh系列和C系列,感觉收获很大,但总有种拾人牙慧的感觉,如果能把笔记对应的参考书籍或者文档链接也发一下,就再好不过了,我想对照着看看,这样不仅能巩固一下,也能学学如何做笔记的。

ch11(内存管理)中代码注释的问题

2.void指针 中的第一段代码

int x = 10;

void* p = &x; // 整数指针转为 void 指针
int* q = p; // void 指针转为整数指针

这里的两行注释是不是顺序颠倒了,第一行不应该是无类型指针p转为int类型指针吗?还是我理解有问题?

几条建议

flow-control 9 goto 语句

goto 的一个主要用法是跳出多层循环。
上面代码有很复杂的嵌套循环,不使用 goto 的话,想要完全跳出所有循环,写起来很麻烦。

一般来说可以提取成一个函数,return时就全跳出了。


function 7.1 extern 说明符

对于多文件的项目,源码文件会用到其他文件声明的函数。这时,当前文件里面,需要给出外部函数的原型,并用extern说明该函数的定义来自其他文件。

函数的声明不需要extern,后面specifier这一章里也说了。


string

对于字符串常量,只在最开始写char* s = 'xxx';,等到引入无法修改的问题后,之后的代码一直用const char *


struct

一般不说“struct命令”吧。

file.md笔误

一、第10项 fscanf():......而fscanf()是从文件读入数据,它的原因定义在头文件stdio.h......

此处应该是“它的原型定义在头文件stdio.h”

二、第13项fwrite(): fwrite()以及后面要介绍的 fwrite(),比较适合读写二进制数据......

此处应该是指后面的 fread 函数吧

第10章

“如果采用第一种写法,由于字符数组的长度可以让编译器自动计算,所以声明时可以省略字符数组的长度。”
应为“第二种写法”

标准库章节-errno.h

取值范围错误(ERANGE):函数的返回值太大,无法用返回类型白哦是。

这里最后的'白哦是'是不是写错了?
还是故意卖萌呢?😆

第2章 关于注释会被替换为空格的说明麻烦举个例子

image

___min/* space */Value 这个写法的场景是什么样的?

如果是在字符串内, 那么它是完整的字符串,不存在替换为空格的这种说法.

如果是正常语句, 我印象中C语言里面没有这种写法, 希望能举个例子说明一下?

image

update:
自己找到答案了:

image

%a 和 %A 并非单独的"浮点数"

  1. 我认为 %a%A 的说明应该改为 "十六进制浮点数的p-记法", 或者网上常见的 "浮点数、十六进制数字和p-记数法".
  2. %f 才是 "浮点数".

pointer.md章节-指针的运算

short* j;
j = (short*)0x1234;
j = j + 1; // 0x1236
j = j + 2; // 0x1238
对于加1的结果解释是“向高位移动两个字节”(这句话是不是有点问题?);
两个字节对于二进制来说是16位,意思是向高位即左移动16位吗?
我将0x1234转换成二进制是0001001000110100,0x1236转换成二进制是0001001000110110,也就是说加1在二进制层面来说是加了10,加2是二进制上面是加了100,这样理解才对吧?
以上是我的一些想法,有说的不对的地方,望老师不要介意 :)

关于I/O函数一章中输入" -13.45e12# 0"之后执行scanf

文中说这时候%f会读到-13.45e12 我觉得应为.45e12
image

    int x;
    float y;
    // 用户输入 "    -13.45e12# 0"
    scanf("%d", &x);
    scanf("%f", &y);
    printf("%d %f", xx, y);  // -13   449999994880.000000
                                   // 450000000000    -> .45e12
    float k = .45e12;
    printf("\n%f", k);  //          449999994880.000000

   // 考虑浮点数精度误差 输出应为.45e12

snprintf 返回值超过 n

文中写到 snprintf 返回值应该小于 n
但是实际测试会超过 返回格式化后的总字符长度

代码

size_t size = snprintf(s, 5, "%s%s33", "11", "22");

printf("size :>> %zu\n", size);
puts(s);

返回值

size :>> 6
1122

编译器

Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin19.6.0

我也查了几个文档
c 的文档好像没有详细说
https://en.cppreference.com/w/c/io/fprintf
有一个 c++的文档好像是说超过的字符会计入返回值
http://www.cplusplus.com/reference/cstdio/snprintf/

指针-1.简介-第二段的 Char 应为 char

字符*表示指针,通常跟在类型关键字的后面,表示指针指向的是什么类型的值。比如,Char*表示一个指向字符的指针,float*表示一个指向float类型的值的指针。

这里 Char* 我认为是笔误,小写 char 才是 C 语言的内置类型。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.