1、求下面函数的返回值
1. `int func(x)`
2. `{`
3. `int countx = 0;`
4. `while(x)`
5. `{`
6. `countx++;`
7. `x = x&(x-1);`
8. `}`
9. `return countx;`
10. `}`
问:假定x是9999,那么返回多少?
答:返回的是8,解题思路是将x转化为二进制,看含有多少个1,则就返回多少。
2、文件中有一组整数,要求排序后输出到另一个文件中
如果数不多的情况下,可以直接将文件中所有整数读到set
中,set类型会自动排好序,读完后再将所有整数写到另一个文件中去。
而整数特别多内存又不够的情况下,可以分批读,每次读一部分排好序写到一个小文件中去,直到所有整数都读取完成,这时每个小文件就都是排好序的了,然后将所有小文件中第一个数读出来进行比较,选出最小的放到目标文件中去,然后将该最小的数所在文件的下一个数读取出来进行比较,这样所有小文件都比完之后,目标文件中就是排好序的所有整数了。
思路:这里采用的是大而化小,化整为零的手段。
3、使用递归将两个有序链表合并为一个有序链表
思路:理解递归,并定义好结束的条件
1. `Node * Merge(Node *head1, Node* head2)`
2. `{`
3. `if (head1 == NULL)`
4. `return head2;`
5. `if (head2 == NULL)`
6. `return head1;`
7. `Node* head = NULL;`
8. `if (head1->data < head2->data)`
9. `{`
10. `head = head1;`
11. `head->next = Merge(head1->next, head2);`
12. `}`
13. `else`
14. `{`
15. `head = head2;`
16. `head->next = Merge(head1, head2->next);`
17. `}`
18. `return head;`
19. `}`
4、写一个函数找出整数数组中第二大的数
1. `const int minnumber = -32767;`
2. `int find_sec_max(int data[], int count)`
3. `{`
4. `int maxnumber = data[0];`
5. `int sec_max = minnumber;`
6. `for( int i=1;I < count; i++)`
7. `{`
8. `if (data[i] > maxnumber)`
9. `{`
10. `sec_max = maxnumber;`
11. `maxnumber = data[i];`
12. `}`
13. `else`
14. `{`
15. `if (data[i] > sec_max)`
16. `sec_max = data[i];`
17. `}`
18. `}`
19. `return sec_max;`
20. `}`
思路:定义两个变量一直保存最大的两个整数
5、如何判断一个单链表是否有环
1. `struct node`
2. `{`
3. `char val;`
4. `node* next;`
5. `}`
6. `bool check(const node* head)`
7. `{`
8. `if (head == NULL)`
9. `return false;`
10. `node* low = head,*fast = head->next;`
11. `while(fast != NULL && fast->next != NULL)`
12. `{`
13. `low = low->next;`
14. `fast = fast->next->next;`
15. `if (low == fast)`
16. `{`
17. `return true;`
18. `}`
19. `}`
20. `return false;`
21. `}`
思路:第一个节点每次走一步,第二个节点每次走两步,即第一个节点走n步的时候,第二个节点走了2n步,如果是有环的链表,n和2n处必定是同一个节点。
6、一个标准的strcpy函数
1. `//strcpy的实现:`
2. `char * strcpy(char* strDest, const char* strSrc)`
3. `{`
4. `assert( (strDest != NULL) && (strSrc != NULL));`
5. `char *address = strDest;`
6. `while( (*strDest++ = *strSrc++) != ‘\0’);`
7. `return address;`
8. `}`
返回char*的原因:返回strDest的原始值使得函数能够支持链式表达式,增加了函数的附加值。同样功能的函数,如果能合理地提高函数的可用性,自然就更加的理想。
7、嵌入式系统可能用到这样的场景,即要求设置一绝对地址为0x67a9的整型变量的值为0xaa66,怎么设置?
1. `int *ptr;`
2. `ptr = (int*)0x67a9;`
3. `*ptr = 0xaa66;`
8、下面的代码输出是什么?为什么?
1. `void foo(void)`
2. `{`
3. `unsigned int a = 6;`
4. `int b = -20;`
5. `(a+b) > 6?puts(“>6”):puts(“<=6”);`
6. `}`
结果是”>6”,原因是当表达式存在有符号类型和无符号类型时所有的操作对象都自动转换为无符号类型,因此-20变成一个非常大的整数与6相加,所以该表达式计算出的结果大于6.
9、strncpy和snprintf的正确用法
1. `//strncpy的正确用法:`
2. `strncpy(dest,src,sizeof(dest)-1);`
3. `dest[strlen(dest)] = ‘\0’;`
4. `//snprintf的正确用法:`
5. `snprintf(dest, sizeof(dest)-1, “%s”, src);`
总则:
- snprintf的使用比strncpy简洁
- snprintf可以获取被拷贝的字节数
- 二者都有性能问题,如果src长度远大于dest,用strncpy,否则用snprintf。
10、printf中%5.3s,这样的怎么看?
1. `int main(void)`
2. `{`
3. `printf(“%s, %5.3s\n”, “computer”, “computer”);`
4. `return 0;`
5. `}`
输出:computer,com
-
%5.3s 或者是 %5.3d 中小数点后面表示输出的最大宽度,小数点前面的表示输出的最小宽度;
-
%5.3f则表示输出场宽为9的浮点数, 其中小数位为3, 整数位为1, 小数点占一位, 不够9位右对齐;
-
默认都是右对齐, 若是%-7s则输出左对齐