考驗基本功的時刻到了,各位大大猜猜下面這些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位數的二倍,自然 丟失的情況不一樣。
屏幕快照 2016-12-15 14.24.24.png