C programe
long long 8B
{
int i=1;
i *= i-=2;
print i ; =1
}
+a return const
-a return var
no +++a / ++-a : gcc have bug
gcc -s xx make to huibian
= nice > , nice
2 num exchange operate way!
a = a + b;
b = a - b;
a = a - b;
当swap(a,b) a=a+b,b=a-b,a=a-b 时 a != b
a++ + a++ + a++ = 3 because x++ more than =
a ^= b ^= a ^= b;
^= have bug!;
EOF = -1;
scanf("%d",yy); input d into yy , yy is address >|>
------------------------------------------------------------------------------------------------------------------------
比较 辨别时
先是把两边的数都转换为相同类型(以更经准的为标准 如: int i=1;flaot j=1.1f; 则(i==j) 为 false
比较操作会使类型提升,然后在比较
问题: 1 在vim里怎么查找 某函数的源文件???? shift+k
2 printf()函数的变化参数怎么实现的!!!
#include
va_list var;
va_start(var ,value(first argument));
va_arg(var , type(int,flaot,.///));
va_end(var);
------------------------------------------------------------------------------------------------------------------------
相同的指针访问 在某些情况下 比下标访问更快!! 如 i++ , 与固定数字相乘 编译时的运算更少一些!
函数 怎么找到的? shift k
vim %!xxd 查看2进制文件 -r 变回来
auto
register
static
extern
global const 是真正的常量在rodata段里 而局部const并不是常量在 stark里 (只是编译器不准修改)
const只能const它后面的那个值
这些地址都是虚拟地址 () 要通过转换表来调用 实际 物理地址中的数据 , 这就是内核做的事.
进程空间 (共3G) :(从3G-0) =
stark ->(高地址到低地址) | (auto变量) 局部的const
heap ->(低地址到高地址) | (malloc申请的)
bss(未初始化段) | (全局变量,static变量 : 未初始化时)
data(低到高) | (全局变量,static变量 : 初始化时)
rodata(只度数据段) | (常量 " " ) 如: int *p = "xdsfaf"; p就指向rodata,是不能写的 *p = 'x' 会出错! global const .
test(代码段) |
... |
bss data rodata test 在编译时就确定了
清楚每个变量所处进程空间的位置 !!!!!!!!! (从执行需求的角度来理解. !!!!)
可执行文件组成????( 查) ELF 类型可执行文件.什么是什么时候才要的
可执行文件(保存已经初始化的值!!! 要把初始值存在文件里 -- 这就是初始和非初始的区别) 和进程空间.
gcc -Wall 打开所有警告 -g gdb调试
printf("%p") 打印地址
递归~~
shift+k 在vim里面函数在哪个头文件>?
cvs checkout
cvs update
cvs add
------------------------------------------------------------------------------------------------------------------------
offsetof(struct v,var) 可以获取结构体中某一量离其实位置的距离数。
指针就是 4个字节的 无符号数, 就是地址
因为是4个字节所以 能找到的空间为 2^32 = 4G
printf("%p",main) %p为打印地址
NULL = (void *)0 ??? , (void *)可以匹配任何类型指针, 目的就是告诉 这个值是指针。
int p[10] = {}; 初始为0. 最好不要这样用!
数组最多分配空间 int[31?,???? 多].char[12??,????]
malloc() 最大小于 0xafff ffff
数组分配空间是 从低到高的 (大端 小端!)
struct xx
{
unsigned aa : 2
unsigned bb : 3
}
段位的实现 也通过位操作实现 , 编译器转换为目标程序时也是通过 位实现的
所以 段位只是为了方便 操作!。
union {
int a;
float b;
} fi = { 3 }; 初始化时是 初始第一个!
函数结束时 并不保证内核把 申请的空间回收!!!
(void *)++ 是加1
void* malloc(size_t size);
void* calloc(size_t number, size_t elementsize);//空间自动初始为0
void* realoc(void* ptr, size_t new_size);
malloc(num) 总会多分一点 多多少???? google!
向内核申请 空间时 是按页申请的。 并不是按 输入要求。
向高地址扩展的。
realloc(), 能扩展就扩展 不能扩展就重新开辟一段空间。 复制过来原来的。以前的free掉!
------------------------------------------------------------------------------------------------------------------------
转换表!
函数指针的数组!
写宏时 有几个语句时 注意
如:#define hong() xx;xx;xx;
while() hong()
这时只在while里执行了一个XX
char *p = "xxxx";
char q[] = "xxxx";
两者是不同的 p指向rodata段 不可修改
q指向stark段 可修改
char *p = (char [])("Xxxx");C99 里才提供的!!!
这时就是在 stark 段.
编译器自定义的宏
有:
__FILE__ 文件名
__LINE__ 当前行
__DATE__ 编译日期
__TIME__ 编译时间
__STDC__ 当前编译器标准
传说中的三种宏技巧:
1 如 #define PRINT(FORMAT,VALUE) printf("the value is "FORMAT"\n",VALUE)
就是可以 用“”“”连接字符串
2 可以用#xx 把xx插入字符串中如
#define PRINT(FORMAT,VALUE) printf("The value of"#VALUE"is"FORMAT,value)
or #define PRINT(VALUE) printf(""#VALUE)
3 可以用##连接符号
#define ADD_FI(value) sum##value = 4 // ADD_FI(3) 等价于 sum3=4;
在每个.h文件中加上
#ifndef _XXX_H
#define _XXX_H
...
#ENDIF
防止重复嵌套
I/O函数!!!
同时打开文件个数至少 8个
perror(const char*s) 打印错误格式为 s:xxx(xxx为错误解释)
fflush() 清空
getchar(); putchar();
fgets();fputs(); //读写
fscanf();fprintf();
ungetc();
fread();fwrite();
fseek();ftell();
fgetpos();fsetpos();
rewind();
setbuf(); //改变缓冲方式。
setvbuf();
feof(); //判断文件状态
ferror(); //判断文件错误
clearer(); //清空
tmpfile(); //建立临时文件
tmpnam(); //删除临时文件
对文件的读写操作通常不能直接顺序操作。
需要用 fseek 来指定操作点。
------------------------------------------------------------------------------------------------------------------------
strlen() 计算字符串个数时不把最后的'\n'计算在内
extern xxx ; 只是有说明效果!!!不是定义
考虑边界问题的两个原则:
1 。从最简单的情况下分析,然后将结果外推。
2 。仔细计算边界,决不掉以轻心。
解决边界问题技巧: 采用 半开半闭原则如:
for(i=0;iwhile( --n >=0 ) 同上。
因为取数组不能返回数组中所有元素值,所以C就规定 返回这个数组的首地址。
所以 int p[];
&p p 值相等,类型不同
*(p)就等于 此数组的第一个元素。
*(&p)等于数组
检查有符号溢出可以采用下面方法:
INT_MAX 是一个已定义的常量,代表最大整数值。
检测相加溢出!
if( a > INT_MAX - b) 溢出!;
可变输入参数的使用!!!
#include
void fun(void first, ...)
va_list var
va_start(var,first)
va_arg(var,type)
va_end(var)
gcc -o xx xx.c -g 生成调试信息 然后可以
gdb xx
r 来调试。
------------------------------------------------------------------------------------------------------------------------
使用宏时 要避免 参数中有 副作用的 表达式。
使宏类表达式 而非语句 更安全。
如
#define assert(e) \
((void)((e) || _assert_error(__FILE__,__LINE__)))
参数最多出现一次
定义内型时 最好用 typedef 而不是宏
因为
#define struct tata* T1
typedef struct tata* T2
T1 a,b; 此时b就不是指针了。
T2 a,b;
>> he << 移位操作符 最多移动不能超过 移位数据的位数且不能为负如
int a, int is 32bit
则可以 a >> 0 , a >> 31 , a >> 32 和 a >> -1是不合法的
比较 > == < 操作时会出现类型提升 !!!!!!
== 优先高于 赋值 = 和 位操作
位操作小于加减;;
switch()
{
case x:
derr:
}
中的标号!!可以任意制定.
作业!。
最大重复字串 。
+ - * % () 运算。
9 + 3 * 33 / 33 -3
147129807
------------------------------------------------------------------------------------------------------------------------
c中操作数的计算次序是根据 编译器来确定的。
函数的参数传递 并不是简单的从右往左 压入堆栈。!!
如果想传递真个数组内容 可以通过:
struct aaa{
int xx[xxx];
} ;
将数组放到结构体中,然后传递结构体实现。
函数参数的例子: 常用 signal() 的原型申明!! 来说明。!
void( *signal(int sig,void(*func)(int)))(int);
尽量使用
struct tag{};
而非 typedef struct tag{}; 更清晰!
gets() the data no '\n'
fgets() the data have '\n'
cc -o xxx.so -G xx.c
use xx.c make a xxx.so(the share object, dynamic lib)
cc xx.c -L/xxx/xx -R/yyy/yyy
tell cc link and run time how to find the direcatory.
.so is dynamic lib
.a is static lib
cc -lname = cc -llibname.so
command nm can find something about function
must put the most right cc xxx -lxx
command : ld about link report
a.out = assembler output
ox0407 is myth number.!!!!
ELF Extersible Linker Format
In UNIX segments is a binary block about file.
use command : size can look the segments of a programme.
nm ,can too
BSS = Block Started by Symbol. is a fadel command in IBM704 assembler language. some people call it Better Save Space.
BSS segment cant put space in object file.
!!!!
1 data segments save in the object file.
2 bss segments dont save in the object file just save size of var.
3 test segments most easy to change the size because gooder.
4 size of a.out is affected by bianyi in debug,but size of segment.
p:120 (int
alloca() can get stack space
setjump(jump_buf j) record the information now
longjmp(jump_buf j,int i) bact to (j)(come from j). is different goto
can use i to distinguish different jump.
------------------------------------------------------------------------------------------------------------------------
think how to change the function return address.
malloc free use
brk sbrk , adjust break printor , it printor heat
mmap//\\ munmap//\\
vmstat
objdump -D show segments
objdump -d show test segments
bus error must duiqi
caculate num of 1 bit
int func(int num)
{
int count = 0;
while(num != 0)
{
count++;
num &= num - 1;
}
return count;
}
a ^= b^= a^= b; array cant run.
a continue. -> -> -> -> have problem .
------------------------------------------------------------------------------------------------------------------------
segments have 3 means ,
prionter of function must return value same
example:
i
int func(int a,int b,int c)
function rule!!!
int c | addr...
int b |
int a |nt func(int num,int bum)
int (*p)() = func;
------------------------------------------------------------------------------------------------------------------------
printf("%.*s",n,str) 可以打印str的前n个字节。
printf("%2$s")
gcc -E xxx.c > xxx.i 预处理完了结果
gcc -E xxx.c -o xxx.i
strerror(error).#define XXX(...) printf(__VA_ARGS__)
typeof()
getch(), soon get a char.
宏的可变参数。
use printf operate guangbiao
gcc mke to exec.
.c ->(yuchuli) gcc -E -> .i ->(bian yi)gcc -S -> .S -> (huibian) gcc -c -> .o -> exec
gcc -c xxx.i.s -> exec
make static lib;
gcc -c .. .o
ar rcs libname.a *.o
make dynamic lib:
gcc -fPIC -g -c xxx.c -o xxx.o
gcc -shared -o libname.so *.o
to exec:
gcc -l -Lpath
LD_LIBRARY_PATH
export LD_LIBRARY_PATH
/etc/ld.so.conf.d/xxx.conf
ldconfig
ldd look need lib.
nm exec look info.
strip asf.o
------------------------------------------------------------------------------------------------------------------------
1.3 2.1 2.2 2.3
1.4 1.5 1.6 2.5
#pragma pack(1) 以1个字节对齐
__attibute__((packed)) 高诉编译器以1个字节对齐
char xx[0]; 可以使用这种方式来记录地址信息
strcut stu{
int num;
int ***;
char name[];
};
可以! sizeof(struct stu) = 8;
strcut stu{
int num;
char name[];
int ***;
};
不行 , name不能扩增就不行 。。。。。。
前者name可以扩展。。。。。 相当于 struct...接着的空间也可以用name来使用。
-----------------------------------------------------------------------------------------------------------------------------
setbuf(FILE *stream, char *c)
缓冲方式有: 无缓冲/ 行缓冲 / 完全缓冲 !
setvbuf(FILE *,* buf, mode, size);
当size小于某值时 都规定为无缓冲。 128
sync
-----------------------------------------------------------------------------------------------------------------------------
c中 enum 中的值被看作整形。
而c++中 则类似宏。
结构体初始化可以:
struct xxx n{
.xx = xx;
.yy = xdd;
}
查看ELF
objdump -d D S
readelf -h
ar -t xx.a 可查看xxx,a的组成。
ar -x xxx.a 可以解压xxx.a静态库
gcc --verbose 可打印整个编译过程。
-fno-builitin bu bb不优化
-----------------------------------------------------------------------------------------------------------------------------
fopen(xa!) xx 可以是设备文件。/dev/xx;
p 为指针/
free(p);
p的内容不变。
q = p;
p = realloc(p,p);
p 的内容会变化.
q 不一定等于 p;
void func()
{ func();}
递归时注意,堆栈空间溢出!!.
{ } n内可以定义变量
c99前只能先定义,在语句中不能定义。
宏的副作用。
使用 static inline 内联函数代替宏
端位~~!
32位
大端:4321;
小端:1234;
16位
大端:21
小端:12
字节对齐。
windows
#pragma pack(1) 以1个字节对齐
linux
__attribute__((packed)) 编译器以1个字节对齐
文档规定!!!端位, 字节对齐。
sorce insight
看源码 软件。
cygvion
----------------------------------------------------------------------------------------
问题
gcc -I -L能不能递归收缩
Makefile 中的变量会不会被覆盖?
Makefile.am 定义子目录宏的时候会不会?
--------------------------------------------------------------------------------------------
10进制小数表示为2进制时会出现无限循环。产生误差。
如float a=0 , for(i=0;i<1000;i++) a+=0.1;
printf(f,a); 就会出现误差。!@
解决方法是现转换为整数int行进行计算 然后再转换回来。!
-------------------------------------------------------------------
问题:
inline 和 #define 的区别
xx.h
static void fun();
#inlcude "xx.h"
static void fun()
{
;
}
gcc -Wall 会有警告 Why?
------------------------------------------------------------------------------------
p 为指针/
free(p);
p的内容不变。
q = p;
p = realloc(p,p);
p 的内容会变化.
q 不一定等于 p;
void func()
{ func();}
递归时注意,堆栈空间溢出!!.
用于调试
#ifdef DEBUG
#endif
assert(expertion);
//一个宏
//当expertion为假时会出现错误信息提示.
//当定义宏 NDEBUG时assert会 在编译时自动去掉。
阅读(698) | 评论(0) | 转发(1) |