前言:
每日一練系列,每一期都包含5道選擇題,2道編程題,博主會盡可能詳細地進行講解,令初學者也能聽的清晰。每日一練系列會持續更新,暑假時三天之內必有一更,到了開學之后,將看學業情況更新。
五道選擇題:
1、以下 scanf 函數調用選項中, 錯誤的是( )
struct T
{
char name[20];
int age;
int sex;
} a[5], *pa=a;
A、scanf("%s",a[0].name);
B、scanf("%d", &pa[0].age);
C、scanf("%d",&(pa->age));
D、scanf("%d", pa->age);
解析:首先,你要明白scanf需要什么,它需要地址,你只要給它對應數據的地址,它就會根據地址對你所給的目標進行修改。
選項A,通過結構體數組訪問到結構體,再通過結構體訪問到結構體成員,但它訪問的是字符數組,而字符數組的本質就是指針,故A正確。選項B,使用結構體數組的方式訪問結構體,再通過結構體訪問結構體成員,不同于A的是它訪問的是整型變量,整型變量沒有字符數組那么特殊,因此要取地址,它也取了,故B正確。
選項C,使用->的方式取到了結構體成員,并取了地址,和B雷同,C正確。D選項,與C不同的就在于沒有取地址,因此,scanf無法正確地執行,故D錯誤。
2、關于指針下列說法正確的是【多選】( )
A、?任何指針都可以轉化為void * B、?void *可以轉化為任何指針
C、?指針的大小為8個字節? ? ? ? ? ?D、?指針雖然高效、靈活但可能不安全
解析:C錯誤,因為指針的大小是隨著平臺的變化而變化的,當指針處于32位平臺時,大小為4,為64位平臺時位8,ABD沒有問題。?
3、請指出以下程序的錯誤【多選】( )
void GetMemory(char** p, int num)
{if (NULL == p && num <= 0)//1return;*p = (char*)malloc(num);return;
}
int main()
{char* str = NULL;GetMemory(&str, 80); //2if (NULL != str){strcpy(&str, "hello"); //3printf(str); //4} return 0;
}
A、1? ? ? B、2? ? ? C、3? ? ?D、4
?解析:代碼1錯誤,因為得同時滿足兩個條件才會直接報錯,但很顯然,我們的目的是令num>0,p!=NULL,因此一個有誤就得報錯。
在語句GetMemory(&str,100);中傳入str的地址,在語句char*str=NULL;中str初始化為空指針,但是str指針變量也有地址,所以參數char**p里面的p保存的是指針變量str的地址,所以調用GetMemory函數之后,動態開辟的空間的地址存放在了str中,在函數返回之后沒有釋放內存,但是這不會導致程序錯誤,只會導致內存泄漏。故代碼2無誤。
代碼3錯誤,&str相當于是對地址的地址進行操作了,沒操作到該操作的。代碼4是正確的,相當于printf("hello");綜上所述,選AC
4、下面這個程序執行后會有什么錯誤或者效果【多選】( )
#define MAX 255
int main()
{
unsigned char A[MAX], i;
for(i = 0; i <= MAX; i++)
A[i] = i;
return 0;
}
A、?數組越界 B、?死循環 C、?棧溢出 D、?內存泄露
解析:選項A,觀察代碼可以看出創建的數組大小為255,因此,數組下標最大為244,i<=MAX的條件一定會令i達到255,會越界。選項B,每次循環i++,MAX的值是定值,好像不會造成死循環,但i是unsigned char型的,因此,i最大為255,當要超出255時就會像一個圓繞回到0,所以會導致死循環。
C選項,創建的臨時變量,在棧中,應該會由系統自動釋放,所以是不存在內存泄漏的問題。棧溢出:屬于緩沖區溢出的一種。棧溢出是由于C語言系列沒有內置檢查機制來確保復制到緩沖區的數據不得大于緩沖區的大小,因此當這個數據足夠大的時候,將會溢出緩沖區的范圍,D選項,無稽之談,我都沒有申請空間,所以根本不會有內存泄漏。綜上所述,答案為AB
5、請問下列程序的輸出是多少( )
#include<stdio.h>
int main()
{unsigned char i = 7;int j = 0;for (; i > 0; i -= 3){++j;}printf("%d\n", j);return 0;
}
A、2? ? ?B、死循環? ? C、173? ? D、172
解析:unsigned char 型的范圍為0~255,為負數的時候也會像圓一樣繞回來,反著繞。觀察代碼,i被初始化為7,每次進行循環i-3,i>0循環繼續,每次循環j++,最后打印出j,目標計算循環次數。i=7,循環到i=-2時,由于unsigned char的特殊性會令i=254,254/3=84余2,即i=2,再使i=-1,由于特殊性,i=255,255/3=85,i=0,循環結束。綜上所述,循環次數為3+84+1+85=173,故選C
編程題1:
力扣(LeetCode)官網 - 全球極客摯愛的技術成長平臺
?思路:猜中次數很好計算,一次循環就可以計算出來,難的是偽猜中的次數。首先,猜中不能被算作偽猜中,那么一旦猜中,那兩個被猜中的槽就可以看作配對成功,不用再考慮,可以把它們置為-1。在后期的判定中,一遇到-1便continue切換槽位即可,而一旦偽猜中成功,那兩個槽也相當于廢掉了,不能在同一個槽偽猜中多次,這是一個隱藏規則,所以把這兩個槽也置為-1
#include<stdio.h>
#include<stdlib.h>
int* masterMind(char* solution, char* guess, int* returnSize) {*returnSize = 2;//初始化返回的數組,因為我們僅僅只需要返回猜中次數和偽猜中次數,所以必定為2int* order = (int*)malloc(sizeof(int) * 2);//創建返回數組int i = 0; int j = 0;int count_true = 0;//猜中次數計數int count_false = 0;//偽猜中次數計數for (i = 0; i < 4; i++)//一共四個槽,所以solution和guess的數組大小都為4{if (solution[i] == guess[i]){count_true++;solution[i] = -1;guess[i] = -1;//由于猜中的槽,偽猜中的不能重復,所以置為-1,用來判定}}for (i = 0; i < 4; i++){if (solution[i] == -1){continue;}for (j = 0; j < 4; j++){if (guess[j] == -1){continue;}if (solution[i] == guess[j]){count_false++;solution[i] = -1;guess[j] = -1;}}}order[0] = count_true;//存放猜中次數order[1] = count_false;//存放偽猜中次數return order;//返回目標}
編程題2:
?
力扣(LeetCode)官網 - 全球極客摯愛的技術成長平臺
?
思路:暴力破解,沒什么好說的,兩個循環遍歷完蛋
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {*returnSize = 2;//只用返回兩個數,所以數組大小必定為2int* order = (int*)malloc(sizeof(int) * 2);//創建一個符合條件的數組int i = 0; int j = 0;for (i = 0; i < numsSize; i++){for(j=i+1;j<numsSize;j++){ //減少循環次數if (nums[i] + nums[j] == target)//找到目標,直接儲存并返回{order[0] = i;order[1] = j;return order;}}}return NULL;//找不到返回空
}
??好了,今天的練習到這里就結束了,感謝各位友友的來訪,祝各位友友前程似錦O(∩_∩)O