C语言总结
Unsigned和Signed比较会变成Unsigned。
malloc
之后就可以使用,但是是Garbage Value。strcpy
等函数注意给dest
预留\0
的内存。typedef struct ht_node* node;
只是一个指针类型,内存为8
字节。不要在函数内返回在该函数内生成的栈内存指针,因为在函数结束时会失效。
inline
内联函数不等于宏,宏会收到钱后运算符优先级的影响。指针算数和类型有关系。
使用
getopt
解析命令行参数。代码:
结果:
Never cast a pointer to a larger type and dereference it, this accesses memory with undefined contents.
Never cast to a smaller type; will truncate (lose) data.
Integer Type Casting:
signed
<->unsigned
: change interpretation of most significant bitsmaller signed
->larger signed
: sign-extend (duplicate the sign bit)smaller unsigned
->larger unsigned
: zero-extend (duplicate 0)
Number mallocs = Number frees
Number mallocs > Number Frees: definitely a memory leak
Number mallocs < Number Frees: definitely a double free
void*
type is C’s provision for generic types.Raw pointer to some memory location (unknown type)
Can cast back and forth between
void*
and other pointer types
Header Files
#include <lib>
for standard libraries#include "file"
for your source filesNever include
.c
files (bad practice)Only include function prototypes/macros; no implementation code!
Header Guards
Double-inclusion problem: include same header file twice
Error:
child.h
includesgrandfather.h
twice.Solution: header guard ensures single inclusion
These functions can return error codes
malloc
could fail.a file couldn’t be opened.
a string may be incorrectly parsed.
Macros
Why macros? “Faster” than function calls
Drawbacks
Less expressive than functions
Arguments are not typechecked, local variables
This can easily lead to errors that are more difficult to find
#define twice(x) 2*x
Not OK,
twice(x+1)
becomes2 * x + 1
Correct:
#define twice(x) (2 *(x))
Always wrap in parentheses; it's a naive search-and-replace!
inline
At compile-time replaces "function calls" with code
More efficient than a normal function call
Less overhead - no need to set up stack/function call
Useful for functions that are
Called frequently
Small, e.g.,
int add(int x, int y);
可以理解为调用时建议编译器进行内联展开,编译的时候可能不会创建栈帧(
pushq
),而是直接运行函数体。static inline
:GCC不会特意为
static inline
函数生成独立的汇编码,除非出现了必须生成不可的情况(如通过函数指针调用和递归调用)。GCC的
static inline
函数仅能作用于文件范围内。
inline
:GCC的
inline
函数相对于普通extern
函数来说只是在同一个文件内调用时建议编译器进行内联展开。GCC一定会为
inline
函数生成一份独立的汇编码,以便其在本文件之外被调用。在别的文件内看来,这个inline
函数和普通的extern
函数无异,GCC的
inline
函数是全局性的:在文件内可以作为一个内联函数被内联展开,而在文件外可以调用它。
例子:
如果不加
static
会报错。Normally GCC’s file scope is “not extern linkage”. That means inline function is never ever provided to the linker which is causing linker error. To resolve this problem use “static” before inline. Using static keyword forces the compiler to consider this inline function in the linker, and hence the program compiles and run successfully.
Macros和
inline
区别:Macros done at pre-compile time
Inline functions done at compile time
Stronger type checking / Argument consistency
Macros cannot return anything (why not?)
Macros can have unintended side effects
#define xsquared(x) (x * x$
Hard to debug macros
errors generated on expanded code, not code that you typed
指针转化
指针的值不会发生任何改变,改变体现在Deferencing的时候。
Cannot dereference expressions with type
void*
Dereferencing a
t *
evaluates to a value with typet
Last updated