錯誤程式碼的個人見解以及邏輯分析題

WJnuHhail發表於2024-11-12

一、程式碼錯誤分析

image

程式碼中的錯誤:
1.src 指標指向字串字面值,不可修改:
字串 "hello,world" 是儲存在只讀區域的常量字串,不能透過指標直接修改。
如果需要倒序操作,需要把字串複製到一個可修改的記憶體中。

2.dest 未正確分配記憶體:
在 malloc(len) 時,沒有為字串末尾的空字元 \0 分配空間。需要分配 len + 1 個位元組。

3.char *s = src[len] 是錯誤的語法:
src[len] 試圖訪問字串越界的位置(len 是字串的長度)。正確的方式應該是設定 s 為指向最後一個有效字元的指標,例如:char *s = src + len - 1;

4.賦值語法錯誤:
d++ = s--; 是無效的,因為賦值運算子的左值和右值型別不匹配。正確的方法是將 *d 設定為 *s,然後遞增或遞減指標。

5.dest 未正確終止:
倒序完成後,需要在 dest 的末尾加上空字元 \0,否則 printf 無法正常輸出字串。

6.未釋放分配的記憶體:
malloc 分配的記憶體未釋放,可能導致記憶體洩漏。

7.函式原型問題:
main() 函式的原型缺少返回型別,應該改為 int main()。


/*
 * Program: Reverse a String
 * Description: This program takes a string and reverses it. 
 *              For example, "abcd" becomes "dcba".
 * Author: [wvjnuhhail@126.com]
 * Date:   [12/11/2024]
 * 
 * Copyright (c) [2024] [wvjnuhhail@126.com]
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    // Original string
    char src[] = "hello,world"; // Mutable string stored on the stack
    char *dest = NULL;
    int len = strlen(src);

    // Allocate memory for the reversed string, including space for '\0'
    dest = (char *)malloc(len + 1);
    if (dest == NULL) {
        printf("Memory allocation failed.\n");
        return 1; // Exit if memory allocation fails
    }

    // Initialize pointers
    char *d = dest;           // Pointer to destination string
    char *s = src + len - 1;  // Pointer to the last character of the source string

    // Reverse the string
    while (len-- != 0) {
        *d++ = *s--; // Copy characters from end to start
    }
    *d = '\0'; // Null-terminate the reversed string

    // Output the reversed string
    printf("%s\n", dest);

    // Free allocated memory
    free(dest);

    return 0;
}


修改的詳細說明:
1.用陣列初始化 src:
原始程式碼中 char *src = "hello,world"; 是一個指向字串字面值的常量指標,嘗試修改它會導致未定義行為。
改為 char src[] = "hello,world";,將字串儲存在棧上以允許修改。

2.正確分配記憶體:
為了容納字串的末尾空字元,需要分配 len + 1 個位元組。

3.修正倒序邏輯:
修正 char *s = src[len] 為 char *s = src + len - 1,指向字串的最後一個有效字元。
使用 *d++ = *s-- 來正確地倒序複製每個字元。

4.終止字串:
使用 *d = '\0'; 在 dest 的末尾加上空字元以形成有效的 C 字串。

5.釋放記憶體:
在程式結束前釋放分配的堆記憶體,避免記憶體洩漏。

二、邏輯分析題

有3個學生 A、B 和 C,他們分別戴上一頂帽子。帽子的顏色有3頂白色和2頂黑色。每個學生都能看到其他學生的帽子顏色,但不能看到自己的帽子顏色。老師隨機取出3個帽子,首先,坐在後面的學生說不知道自己頭上帽子的顏色,坐在中間的學生說自己也不知道自己頭上帽子的顏色,坐在前面的學生說知道自己頭上帽子的顏色。請問最前面的學生帽子是什麼顏色,請說明理由。

### 問題分析:
- **帽子數量**:總共有3頂白帽和2頂黑帽。
- **規則**:每個學生能看到其他兩人的帽子顏色,但看不到自己的帽子。
- **過程**:
  1. 後排學生先觀察前兩人的帽子,說“**不知道自己帽子的顏色**”。
  2. 中排學生觀察後排和前排的帽子,也說“**不知道自己帽子的顏色**”。
  3. 最前排學生透過以上兩人的回答,得出自己帽子的顏色,並說“**知道自己帽子的顏色**”。

---

### 推理過程:
1. **後排學生的判斷**:
   - 如果後排學生看到前排和中排的帽子都是黑色(兩頂黑帽都已被使用),他可以確定自己的是白帽(因為最多隻有兩頂黑帽)。
   - 但後排學生說“**不知道自己帽子的顏色**”,說明前排和中排**不可能同時戴黑帽**。即至少有一人戴白帽。

2. **中排學生的判斷**:
   - 中排學生知道後排學生看不到確定性(即前排和中排不同時是黑帽)。這時,他需要根據後排學生的反應和他自己看到的帽子來推測:
     - 如果中排學生看到前排是黑帽,且他知道自己戴的是黑帽(基於只有兩頂黑帽的限制),則他可以確定。
     - 但中排學生也說“**不知道自己帽子的顏色**”,說明前排不可能是黑帽(否則他可以確定)。

3. **最前排學生的判斷**:
   - 最前排學生聽到後排和中排都無法確定自己的帽子顏色,就可以推斷:
     - 自己的帽子**一定是白帽**。  
     - **理由**:如果自己戴的是黑帽,中排學生一定能確定自己的帽子顏色,因為最多隻有兩頂黑帽,而中排沒有做出確定的判斷。

---

### 結論:
最前排學生的帽子是 **白色**。

---

### 關鍵邏輯:
1. 如果後排學生說“**不知道**”,說明前排和中排不能同時是黑帽。
2. 如果中排學生也說“**不知道**”,說明前排不可能是黑帽。
3. 最前排學生透過以上兩點推斷,自己的帽子一定是白色。

相關文章