考验基本功的时刻到了,各位大大猜猜下面这些code的输出是什么?
1 . typedef跟define的区别?
#define char_d char*
typedef char* char_t;
int main(void)
{
char_d p,q;
printf("sizeof(p)=%dsizeof(q)=%d\\n",sizeof(p),sizeof(q));
char_t x,y;
printf("sizeof(x)=%dsizeof(y)=%d\\n",sizeof(x),sizeof(y));
return0;
}
2 . 内存对齐原则(linux下)?
#pragma pake(8)
struct Student
{
char a; short b; int c; int d; double e;
};
struct Student1
{
char a; double e; short b; int c; int d;
};
union Student2
{
char a; double e; short b; int c; int d;
};
printf("sizeof(t) = %ld \\n",sizeof(struct Student)); // 请问输出什么?
printf("sizeof(t1) = %ld \\n",sizeof(struct Student1)); // 请问输出什么?
printf("sizeof(t2) = %ld \\n",sizeof(union Student2)); // 请问输出什么?
3 . 下面代码作为单链翻转,有问题吗?
typedef struct node
{
int data;
struct node * next;
} Node;
void reverseList (Node * head){
Node * tmp = head->next;
Node * p;
while (tmp->next) {
p = tmp->next;
tmp->next = p->next;
p->next = head->next;
head->next = p;
}
}
4 . 编写程序:输入一整数n,输入1-n的全排列;
例如:
输入 3
输出:123 132 213 231 312 321
5 . 下面代码输出:
void question2(){
char a[1000];
int i ;
for(i=0;i<1000;i++){
a[i] = -1-i;
}
printf("%lu \\n",strlen(a)); // 0 截断
}
6 . 下面代码打印结果是0?
int arr[10][10];
int (* p) [5] ;
p = arr;
printf("%lu \\n", &arr[5][3] - &p[5][3]);
7 . 不使用第三方变量,第三方函数,将下面的字符串逆序打印出来?
char *p = "234g4jhg21jh3g12jh";
8 . 如何判断下面单链表是否有环呢?
typedef struct node
{
int data;
struct node *next;
}DNode;
9 . 思考一下,下面的代码输出几个pass?
float f1 = 20.3;
double d1 = 20.3;
if (f1 == d1) {
NSLog(@"pass");
}
float f2 = 20.5;
double d2 = 20.5;
if (f2 == d2) {
NSLog(@"pass");
}
float f3 = 20.6;
double d3 = 20.6;
if (f3 == d3) {
NSLog(@"pass");
}
、 别偷看答案,自己先好好想想。
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
、
答案:
1 . 输出结果:
sizeof(p) = 8 sizeof(q) = 1
sizeof(x) = 8 sizeof(y) = 8
提示:没有答对的 可以看看预处理后的代码;
gcc -E main.c -o main.i
vim main.i
2 . 输出结果:
sizeof(t)=24
sizeof(t1)=32
sizeof(t2)=8
提示:没有答对的,自己可以参考下边原则;
/***
#pragma pack -> 程序编译器对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。
* 内存对齐规则:
* 1. 取 pake(n) 中的值 , 去结构体中最大类型的大小 m ,两者取小 即为外部对齐 其大小y = min(n,m);
* 2. 将每一个结构体的成员大小与 y 比较 ,取小为x,做内对其大小;
* 3. 假设起始地址为0x00 开始, 能被x整除的地方开始存值;
* 4. 外部对齐原则是根据y值,进行补空操作;
*/
3 . 有问题
将Node * tmp = head->next; 修改为 Node * tmp = head;
并且加上 head.next = NULL; 否则翻转完成之后,最后一个节点的next 不为NULL;
// 核心代码就这两句,每次插入到head的后面,并将新插入进来的tmp指向下一个节点
tmp->next = p->next;
p->next = head->next;
4 . 核心代码,参考如下 (PS:写出来n个for嵌套的同学可以去面壁了。)
void dfs(int step){
if(step == n+1){
for(i=1;i<=n;i++){
printf("%d",steps[i]);
}
putchar(10);
return;
}
for( int i=1;i<=n;i++){
if(book[i] == 0){
steps[step] = i;
book[i] = 1;
dfs(step+1);
book[i] = 0; // 请记得一定要将位置标记为可用
}
}
}
5 . 输出 :255 每答对的可以参考下面的逻辑
第一, strlen 在计算个数的过程中,遇见 '\\0' 就会结束计数;
第二, 在int类型转换成char 的过程中,会切断数据;
1111 1111 1111 1111 -1
1111 1111 1111 1110 -2
1111 1111 1111 1101 -3
...
1111 1111 0000 0001 -255 -> 0
1111 1111 0000 0000 -256
6 . 不是
在 int (* p) [5] = arr; 之后, 可以理解成 p[5][20]
输出结果 :25
7 . 递归
void strRevesal(char *p){
if(*p){
strRevesal(p+1);
printf("%c",*p);
}
}
// 还有一种方式倒置字符串,使用二分的思维方式 , 可以参考一下:
char * str_revesal(char *var){
char *start = var;
char *end = start + strlen(var) - 1;
while(start<end){ // 地址是有高低的
*start ^= *end ;
*end ^= *start ;
*start ^= *end ;
start++;
end--;
}
return var;
}
8 . **思路1 : **
设两个工作指针,一个快一个慢,如果有环的话,它们会必然在某点相遇。
int judgeDList(DNode *head){
DNode *p,*q;
p = q = head;
while(p!=NULL && q!=NULL && q->next!=NULL){
p = p->next;
if(q->next != NULL)
q = q->next->next;
if(q==p)
return 1;
}
return 0;
}
**思路2: **
设两个工作指针p、q,p总是向前走,但q每次都从头开始走,对于每个节点,看p走的步数是否和q一样。比如p从A走到D,用了4步,而q则用了14步。因而步数不等,出现矛盾,存在环。
9 . 输出一个pass:
先说一下原理,计算机存储数据的时候 采用的是二进制,整除初二区域,小数乘2去整。
所以小数除了0.5意外,都会有精度丢失的情况;
这里double是float位数的二倍,自然 丢失的情况不一样。