TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Intermediate C Programming Notes

81 点作者 rockdiesel将近 11 年前

5 条评论

apaprocki将近 11 年前
Solid resource, but definitely a little dated (i.e. no C99). The &#x27;Returning Arrays&#x27; part talks about this:<p><pre><code> char *itoa(int n, char buf[]) { sprintf(buf, &quot;%d&quot;, n); return buf; } </code></pre> ... but you&#x27;d really want to take a length parameter and call snprintf to prevent buffer overflows. This pre-C99 style C is one of the reasons C has a bad rep wrt memory hazards.<p>edit: Anyone interested in this should probably read through something newer, like <a href="http://c.learncodethehardway.org/book/" rel="nofollow">http:&#x2F;&#x2F;c.learncodethehardway.org&#x2F;book&#x2F;</a>
评论 #8060014 未加载
评论 #8059693 未加载
advocaat23将近 11 年前
I think it&#x27;s always weird how multi-dimensional arrays are implemented in most C programming books. Do you guys really use a pointer-pointer approach to represent them? Because nowadays I always allocate a flat array and just calculate the indices. E.g.<p><pre><code> struct dmatrix { size_t rows, cols; double *data; } </code></pre> and then a simple<p><pre><code> double dmatrix_get(struct dmatrix *m, size_t r, size_t c) { return m-&gt;data[r * m-&gt;cols + c]; } </code></pre> is all you need? In particular I find explicit array sizes in function headers very contrived and I have never used them in serious code. Normally it&#x27;s just a pointer and a length argument similar to e.g. read&#x2F;write functions in the standard library.
评论 #8060350 未加载
mgraczyk将近 11 年前
I did not like the &quot;Returning Arrays&quot; section. There are perfectly reasonable ways of returning small arrays in C.<p><pre><code> typedef struct { char c_str[25]; } number_string_t; number_string_t itoa(int i) { number_string_t retval = {0}; int written = snprintf(&amp;retval.c_str[0], sizeof(retval.c_str), &quot;%d&quot;, i); &#x2F;&#x2F; Error checking..... return retval; }</code></pre>
评论 #8059945 未加载
评论 #8059625 未加载
DSMan195276将近 11 年前
This looks like a fairly good read for C programming, but it does seem to be showing it&#x27;s age and has some (now) misinformation. The Copyright is 1996 to 1999, so from what I&#x27;ve looked at this is all C89, no C99 which is what you&#x27;ll probably see at this point if you look at some C code.<p>I admit to not having read the entire thing, but I&#x27;ve looked through most of it. A few things that stood out to me:<p>1. They dance around what a multidimensional array in C actually is, and the line &quot;C does not have true multidimensional arrays.&quot; is simply false. I&#x27;d let it go, but there&#x27;s a disconnect from when they go from sections 23 and 23.1 to section 23.2. Section 23.2 is most definitely <i>not</i> a multidimension array. Allocating an actual multidimensional array is actually much simpler, just malloc a block of memory into a pointer to an array:<p><pre><code> int (*a)[3] = malloc(2 * 3 * sizeof(int)); </code></pre> This allocated array works just like any other multidimensional array in C and can be passed as such, and it&#x27;s much easier to use then the pointer-to-pointer approach. The pointer-to-pointer approach is the only one shown though, as though it&#x27;s the only option, even though it&#x27;s not equivalent.<p>2. In section 18.1.7, type qualifiers, they say &#x27;const&#x27; is fairly rare to see. That may have been true when this was written, but in properly written code today it should be decently common to see, mostly in the case that functions are receiving pointers to data they shouldn&#x27;t be changing and for string literals that shouldn&#x27;t be changed. Not using const correctly is a source for lots of annoying compilation warnings and runtime errors.<p>3. The very end of section 20.1 notes that there is no way to define a variable argument macro. That was true at the time of writing (kinda), but it&#x27;s not true with C99.<p>4. In section 18.3.1, the switch statement, everything&#x27;s perfectly fine except that where it says it&#x27;s common to use a list of #define&#x27;s over a switch. It&#x27;s much better to use an enum type to do so since it can annotate your code a bit better, acts basically the same way, you&#x27;ll get better compilation warnings from it, and in most cases you can let the compiler assign the numbers for you and thus not risk any conflicts from adding and removing options. For whatever reason, I couldn&#x27;t find any info on enum&#x27;s in the entire read, which is a huge red-flag.<p>5. A lot of their function pointer information involves pointers defined as:<p><pre><code> int (*p)(); </code></pre> The huge issue with that is that they defined it with an unknown parameter list, and it was <i>intended</i> by the author. There are basically zero times when you actually want to do that, in most cases you should either include the argument types, such as:<p><pre><code> int (*p)(int); </code></pre> Or put void to indicate no arguments:<p><pre><code> int (*p)(void);</code></pre>
评论 #8059630 未加载
ejr将近 11 年前
This looks to be very good. One tiny, and I do mean tiny, wish is that the code follows BSD&#x2F;KNF style. I know that&#x27;s all down to preference anyway, but it does make things easier to absorb.