一. C:
1. 函数调用调用约定:
1) __stdcall: 1)参数从右向左压入堆栈,2)函数自身修改堆栈 3)返回值在EAX中, 函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸。
如 int __stdcall func( int a, int b ) , 被声明成: _func@8 。进行调用 func(a, ++b)时,相当于 ++b, func((a, b)。
2) __cdecl: 1) 参数从右向左压入栈,2)调用者进行清栈。3返回值在EAX中。由于由调用者清理栈,所以允许可变参数函数存在,如 sprintf。
3) __fastcall: 顾名思义,__fastcall的特点就是快,因为它通过 CPU寄存器来传递参数。他用 ECX和 EDX传送前两个双字(DWORD)或更小的参数,剩下的参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在 EAX中。
4) __thiscall: 这是 C++ 语言特有的一种调用方式,用于类成员函数的调用约定。如果参数确定,this 指针存放于 ECX 寄存器,函数自身清理堆栈;如果参数不确定,this指针在所有参数入栈后再入栈,调用者清理栈。__thiscall 不是关键字,程序员不能使用。参数按照从右至左的方式入栈。
5) __pascal: 压栈从左向右,函数自身清栈。该方式已废弃。
总结:上述5种方式中,除pascal外所有调用方式都是从右向左入栈,__cdecl 因为是调用者清栈而允许可变参数的存在。
VC 默认是 __cdecl 方式 ,而Win API是 __stdcall 方式。VC的默认调用方式可以设置。
gcc 默认是 __stdcal 方式。
2. C的输入输出:
C语言输入输出函数有很多,标准I/O函数中包含了如下几个常用的函数:
输入:scanf, fscanf, sscanf
输出:printf, fprintf, sprintf
输入字符(串):getc, getchar, gets, fgetc, fgets
输出字符(串):putc, putchar, puts, fputc, fputs
scanf: scanf函数的返回值为int值,即成功赋值的个数。scanf("%s[^\n]", str)可以读入空格。
getchar: int getchar(void), 从标准输入流读取一个字符,只有换行时才从缓冲区中读取。
getc: getc( FILE * fp ), 从文件中读取一个字符。getc( stdin ) <=> getchar()
gets: char* gets(char *str), gets主要是从标准输入流读取字符串并回显,读到换行符时退出,并会将换行符省去.
printf:%x, %X十六进制,%o八进制, %u 无符号, %p指针。
Q: 如何输入一行带空格的字符串?
method 1:
scanf("%[^\n]%*c", buf),原理:%[^\n]输入一个以\n结尾的字符串,即一行字符串(\n除外)。%*c输入一个字符(\n)但是不赋给任何一个变量,即吃掉这个字符。
method 2:
gets或fgets用于输入一行, char *fgets(char *buf, int bufsize, FILE *stream)。
3. 常用函数:
<ctype.h>: isdigit(), islower(), isspace(), isxdigit(), tolower(), atof(), atoi(), atol().
<stdlib.h>内存操作: malloc(size), realloc(old_buf, size), calloc(size_1, size_2)分配并刷新内存。
<time.h>时间: time( time * t), 返回1970年1月1日UTC时间到现在的秒数。
<string.h>字符串: strlen(), memset(), memcpy(), strncpy(), strstr(), strok()
<math.h>数学函数: ceil(), floor(), sqrt(), pow(), log(double x)
Q:如何求2^x = 9 中的指数x? 注:log(x) = m <=> e^m = x
x = log(9) / log(2)
二. C++:
1. 输入输出:
cin, cin.get(), cin.getline(), getline(cin, str), cin.goodbit(), cin.clear()清除错误状态。
<sstream>: stringstream 类用于把字符串当作输入输出对象。
cin>>noskipws>>ch可以输入空格、TAB、RET
cin.getline(buf, size, '\n')
getline( cin, string_obj ) 返回 cin, cin.goodbit()返回cin流是否正常。
Q: 用getline输入一行:
2.stl集合类: 顺序容器(vector,deque,list)、关联容器(set,multiset,map,multimap)、容器适配器(stack, queue, priority_queue)。
STL可分为容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adaptors)、算法(algorithms)、仿函数(functors)六个部分。
<algorithm><functional><iterator><utility><memory><numeric>
容器: vector, list, deque(双队列),set, multiset, stack, queue(音q),priority_queue, map, multimap。
迭代器: iterator. 它由<utility>、<iterator>、<memory>这几个头文件组成。
算法:find, sort, copy, replace。
函数对象:bind1st, bind2st, not1, not2。
vector: 使用数组来存放。
list: 使用双向链表存放。front(), back(), push_front(), push_back(), pop_back(), insert(), erase(), swap(), clear(), assign()
dequeue: 类似于list和vector的结合品,每一个堆(Heap)存放若干元素,堆之间通过指针连接。
容器:Iterator( begin, end, rbegin, rend), Capaciti( empty, size, max_size, resize )
操作:splice, remove, remove_if, unique, merge, sort, reverse
标准算法(约70种):
变化:copy, remove, fill, replace, swap
非变化: equal, for_each, count, count_if, search, find, binary_search
算法示例:
Iterator find(Iterator first, Iterator last, const T &val);
void sort( Iterator first, Iterator last)
list_1.sort( greater<int>());
map<T1, T2>::value_type( key, value);
三. Java:
1. 琐碎:
数据类型: byte, char.
修饰符public, private, protected, default: default只允许同一包中调用,protected只允许有血缘关系的晚辈对长辈的调用。
final: Java中无const(const只作为保留), final 变量本身不能被修改,但是它指向的对象可以被修改。final修饰的方法不能被重载。final类不能被继承。
方法覆盖:子类方法与父类的签名、返回值完全相同。子类可以通过super来显示调用父类的方法。
多态:基类引用根据对象的真实子类,调用相应的方法。
类的修饰符:public、default 访问说明符;final 该类无子类、abstrace该类为抽象类。 abstrace能修饰类和方法。
接口:interface, interface 中所有方法都是public、abstrace属性。
包:包无嵌套关系, java.io.*并不是java.*的子包。
内部类:实名内部类、匿名内部类。
比较: == 与 equals, ==是比较变量的值,equals是比较内容。
2.集合类:
Map( HashMap( LinkedHashMap ),HashTable, TreeMap)
Collection( List(Vector(Stack), ArrayList, LinkedList ), Set( TreeSet, HashSet( LinkedHashSet ) ) )
Iterator: hasNext(), next()
List: add(obj), get(int i), size(), iterator()
Set: add( obj ), get( obj )
Map: put( key, value), keSet(), value(), remove()
HashSet: HashSet在存元素时,会调用对象的hashCode方法计算出存储位置,然后和该位置上所有的元素进行equals比较。故equals相同时,程序员要保证hashCode相同。
ArrayList, LinkedList, Vector: 只有Vector是线程安全的,其它两个都不是线程安全的。
HashMap, HashTable: HashTable是线程安全的,不支持null,HashMap不是线程安全的, 支持null。
杂:
1.运算符优先级:
算术、逻辑、关系、赋值。同一优先级的看结合性。
2.补数: char a=127, 则 a+=1, a== -128. (1,000,0000)
负数的补数:符号位为1, 然后让其它位由其绝对值取反+1。
负数的补码:2^8 + x = ...
如:-1为1,000,0001 => 1,111,1110=>1, 111,1111.
-127: 按公式 2^8 + (-127) =1,000,0001
-128: 2^8+(-2^7) = 1,000,0000
3. 进程阻塞与时间片切换时间片切换 并不会引起进程阻塞。
4. 验证两个数之和是否会溢出:
a + b = c, 若溢出,则a和b的符号相同,与c的符号不同。
int test_overflow(int a, int b){
char byte;
int int_size = sizeof(a) * sizeof(byte);
int c = a + b;
int fa = a>>(int_size-1);
int fb = b >>(int_size-1);
int fc = c >> (int_size-1);
printf("%d + %d = %d\n", a, b, c );
if ( !(fa^fb) && (fa^fc) ) printf("溢出。\n");
return 0;
}
5. 指令集:
CISC, RISC
指令操作码分为三种:定长操作码,扩展操作码(指令定长,操作码可以扩展利用单操作数、无操作数的地址空间),霍夫曼指令码。
6.幂指数与异或:
2 ^ 31 - 3 == ?, 由于c/c++无幂指数操作,"^"是异或操作符,位运算优先级比减运算优先级低。故相当于 2^28
n&(n-1) : 将n为1的最低位置为0.
n&(-n): n最末位为1的位数相应的的二进制数. 如 2&(-2) = 2, 4&(-4) = 4, (2+4)&(-2-4) = 2。
n^(-n): 对应 -2, -4, -8, -16, ...这些数
7. c++与java的数组:
c++: int a[]={1, 2, 3}; int a[10]={1, 2, 3}; int *a = new int[10];
java: int [] a = {1, 2, 3}; int a[]= {1, 2, 3}; int a[][];
另外:java 中 int []a 与 int a[] 都可以使用, 但是,推荐使用 int [] a,它明确了a是一个数组类型。
8. java: byte char int:
byte: -128 ~ 127.
char: 0 ~ 65535.
int: -21.... +21..., 约21亿。即 4+4+1=9 个0.
int i = 10000000000000000; 在java中会编译异常,但是在c/c++中编译可以通过。
9. java: FileInputStream.read()
无论二进制文件还是文本文件,都可以用文件输入流java.io.FileInputStream
public abstract int read() throws IOException,这个方法读取字节流中下一个字节。读取的字节值是作为 int 类型返回的。实际返回值的范围是 0 ~255 ,而不同于基本数据类型 byte 的范围,-128 ~+127。如果所有数据都读完了(即所谓的到达流终点),再调用这个方法,则返回-1。这是判定流中所有数据读取完毕的唯一方式。
10. java: String, char, byte:
char [] a = {'你', '好', '妈'};
System.out.println( (int)a.length);
char [] a = "你好吗"; 这一个语句是错误的,不能把 String 转换成 char [] 类型。
11. linux 与 windows编码问题:
如何处理文件名编码不一致的问题:
如何处理windows gbk编码向linux的utf-8转换: iconv -f gbk -t utf-8 file1.txt -o file2.txt
12. java HashTable 与 HashMap:
HashTable 与 HashMap 都是利用Hash方法存储<key, value>,但是HashTable是同步的,HashMap不是线程安全的且其key可以有一个null。另外:HashMap的桶大小初始时为16,其对应的线程安全类使用细粒度锁(每个桶对应一个锁,且每一个桶对应一个计数器,以此来处理访问热点问题)。