第一題
test.c文件中包括如下語句,文件中定義的四個變量中,是指針類型的是()【多選】
#define INT_PTR int* typedef int* intptr; INT_PRT a,b; int_ptr c,d;
A:a ?B:b ?C:c ?D:d
#define是宏定義,此時在程序中INT_PTR都會被替換為int*,變量a,b的定義如下:
int * a,b;
可以發現a確實為整型指針類型,而b則為整型類型。
而typedef是給該類型定義一個別名,使用該別名創建出的變量都是這個類型的。
第二題
對于以下說法,正確的是()
?A:對于struct X {short s;int i; charc},sizeof(X)sizeof(s)+sizeof(i)+sizeof(c )
?B:對于某個double變量a,可以使用a==0.0來判斷其是否為0。
?C:初始化方式char a[14]=“helloworld”;和char a[14];a=“hello world”;的效果相同。
?D:以上說法都不對
解析:
A:結構體大小的計算要考慮內存對齊問題。
B:這道題如果在VS上實驗一下的話,會覺得B選項就是正確的,然而不然,因為該數據是double類型的數據,浮點數存在誤差,不能直接判斷兩個數是否相等,通常是采用比較兩數之差是否小于一個很小的數字,(具體可以自己設定一個這樣的數,作為誤差)來確定是否相等。
例如:
運行結果是不是超脫預料之外?
調試觀察sub1和sub2的數值。
可以發現誤差是存在的,所以不能直接用一個浮點數是否等于0.0來判斷該數是否為0。
C:a為數組首元素地址,是一個常量不可以改變。
第三題
請問下列表達式,哪些會被編譯器禁止()【多選】
int a=248,b=4; int const*c=21; const int*d=&a; int *const e=&b; int const* const f=&a;
?A:*c = 32;
?B:*d = 43;
?C:e = &a;
?D:f = 0x321f;
解析:
這道題是有關const修飾指針變量的題目,要記住只有兩種情況,const在*前邊的位置和const在*后邊。如果const在*前邊,就修飾的是指針變量指向的結果。
例如int a=1;
const int *pa=&a;
int const *pa=&a;只要const在pa的左邊,那么const修飾的就是*pa,就不可以利用解引用得到a來修改a的值,此時a的值被固定了。
還有一種情況是const在*的右邊int a=0;
int b=0;
int * const pa=&a;
這種情況下const修飾的是a這個變量的地址,即pa的指向不能發生變化。此時如果要更改pa的指向如pa=&b,這樣的操作是不被允許的。
如果覺得不好記憶的話,可以參考趣味講解const修飾指針變量。
第四題
對于下邊代碼段,描述正確的是()
t=0; while(printf("*")) {t++;if(t<3)break; }
?A:其中循環控制表達式與0等價。
?B:其中循環控制表達式與‘0’等價。
?C:其中循環控制表達式是不合法的。
?D:以上說法都不對。
解析:
這道題目選B,因為printf函數返回打印的字符·個數,所以判斷條件恒為1,字符零不是零。
所以在這里B選項就是正確的。其他選項都是錯誤的。
編程題
1,至少是其他數字兩倍的最大數
題目要求如下
第一種思路
遍歷兩邊,第一遍找出最大值,第二遍判斷是否找出的最大值是數組每個元素的二倍,如果滿足條件就返回最大數字的下標,如果不滿足,那就返回-1。
代碼如下:int dominantIndex(int* nums, int numsSize){int i=0;int max=0;for(i=0;i<numsSize;i++){if (nums[i] > max){max = nums[i];}}int num=0;int flag=0;for(i=0;i<numsSize;i++){if(nums[i]==max){num=i;}else{if(nums[i]*2>max){flag=1;}}}if(flag==0){return num;}else{return -1;}return 0; }
代碼表達很清晰。
還有一種方法,在找到最大值時,也要保存倒數第二大的值。
代碼如下:int dominantIndex(int* nums, int numsSize){int i=0;int max=nums[0];int max1=0;int flag=0;for(i=0;i<numsSize;i++){if(nums[i]>max){flag=i;max1=max;max=nums[i]; }if (max1 < nums[i]&&max!=nums[i]){max1 = nums[i];}}if(max>=2*max1){return flag;}else{return -1;}return 0; }
找到最大值的同時,保存第二大值,因為后邊可能會出現比已經保存的第二大的值還要大的值,所以要繼續向后遍歷找到真正第二大的值,。最后進行判斷即可。
第二題
自除數
只需要創建一個數組,得到right和left之間的所有滿足條件的數即可,每一個數求出他的個位數,十位數,等等。
數據范圍最大也只有10000。
像這種需要用的數字的每一位的數據進行判斷的題目,最好還是創建一個大小為6的數組,裝輸入的數據的每個位的數字,方便最后進行判斷。在解題的過程中要注意返回的數組必須是malloc申請的,不然就會有很多的報錯。
代碼如下(注釋十分清晰)
int* selfDividingNumbers(int left,int right,int *returnsize)
{int*ccc=(int*)malloc(sizeof(int)*(right-left+1));int kkk[6];int l = 0;for (int i = left; i <= right; i++){ int j = 0;int a = 1;int num = i;while (i > 0)//獲取每位數字{kkk[j++] = i % 10;i = i / 10;}i = num;for (int k = 0; k < j; k++){if (kkk[k] != 0)//如果數字中包含零,就不滿足{if (i % kkk[k] != 0){a = 0;}else{a = 1;}}else{a=0;}}if (a != 0)//如果該數字通過前邊的測試{ccc[l++] = i;//將該數字存放在預留數組中。}}*returnsize = l;return ccc;
}
第三題
喝汽水問題
小明喝汽水,一瓶汽水1元,2個空瓶可以換一瓶汽水,小明現在有n元,求小明可以喝到多少瓶汽水?
思路一
將上述問題以代碼形式解決,如果有n元,那么剛開始就有n個空瓶,假設全部喝完,然后拿著所有空瓶過去換汽水,就能換到n/2瓶汽水,喝完后于是又獲得了n/2的瓶子,然后再去換,直到瓶子數目為0或者為1不足以再換汽水為止。
代碼實現如下
int main()
{int money = 0;//錢數int total = 0;//總共喝的汽水的數量int empty = 0;//空瓶的數量scanf("%d", &money);total = money;empty = money;while(empty>1)//只要空瓶數大于2,就能繼續換{total += empty/2;empty = empty/2+empty%2;}printf("total = %d\n", total);//最終結果totalreturn 0;
}
思路二
利用數學思維求解,我們可以利用上述代碼多運行幾次觀察規律,會發現隨著money的增長,能喝到的汽水的數量是一個等差數列。
1元—>1瓶汽水
2元—>3瓶汽水
3元—>5瓶汽水
。。。。
所以只要Money的數量不為0,只需要返回money*2-1即可。
代碼如下
int main()
{int money = 0;int total = 0;int empty = 0;scanf("%d", &money); //方法2if(money <= 0){total = 0;}else{total = money*2-1;}printf("total = %d\n", total);return 0;
}