跳过正文

丙加·第6章·答案

·360 字·2 分钟·
To @打咩,
既然学的是C++,我就多用C++的风格吧

命令提示符
  1. 修改 value 的值:

    #include<iostream>
    #include<cstdio>
    
    int main() {
        int value = 0xcaffee;
    
        int *ptr = &value;
        *ptr = 0xcacafefe;
    
        std::printf("ptr: %p, &value: %p, *ptr:%d", ptr, &value, *ptr);
        std::cout << "ptr: " << static_cast<const void*>(ptr) 
                  << ", &value: " << static_cast<const void*>(&value) 
                  << ", *ptr: " << *ptr << std::endl;
    
        return 0;
    }
    

    在 C++中要打印指针地址,应该使用 static_cast<const void*> 进行转换,这样可以确保正确输出指针的地址值,而不是尝试将其作为 C 风格字符串处理。这一点在正文里面也提过

  2. 数组输出:

    #include<iostream>
    #include<cstdio>
    
    int main() {
        int arr[5] = {10, 20, 30, 40, 50};
        int *p = arr;
    
        std::printf("p: %p, (p + 3): %p, sizeof(int): %zu\n", p, (p + 3), sizeof(int));
    
        std::printf("arr[3]: %d, p[3]: %d, 3[p]: %d", arr[3], p[3], 3[p]);
    
        return 0;
    }
    
  3. 程序查错:

    #include <stdio.h>
    #include <stdlib.h>
    
    int* risky_function() {
        int local_var = 42;
        return &local_var;    
    }
    
    int main() {
        int *p1;
        *p1 = 100;
    
        // C++风格应该是int *p = new int;
        // 如果要赋值就是int *p = new int(42);
        int *p2 = (int*)malloc(sizeof(int));
        *p2 = 200;
        free(p2);
        int something_else = 300;
        printf("%d\n", *p2); 
    
        int *p3 = risky_function();
        printf("%d\n", *p3); 
    
        return 0;
    }
    
    1. 第一处:int *p1; *p1 = 100;,p1 没有分配合理的内存地址,是 野指针。正确做法见 p2 的声明部分。使用 C 风格和 C++风格理论上都是可以接受的。

    2. 第二处:free(p2); int something_else = 300; printf("%d\n", *p2);,p2 指向的内存已经被释放,但之后又尝试通过 p2 访问这块内存,这是 “使用已释放内存” 的错误,会产生危险。

    3. risky_functionreturn &local_var; 返回的是局部变量 local_var 的地址,外部访问的时候 local_var 可能已经被销毁,造成悬空指针。

      碎碎念:这个代码有概率得到 42,但是如果内存紧张,local_var 的内存有可能会被占用,从而读到垃圾值 汝之蜜数据,我之垃圾,甚至错误访问其他程序的内存导致段错误。

  4. 代码填空:

    #include <stdio.h>
    
    // 函数功能:打印整型数组的元素
    // 参数:arr - 指向数组的指针,size - 要打印的元素个数
    // const目的是防止被意外修改
    // 这里是故意写得很复杂,实际上arr[i]就搞定了
    void print_array(const int* arr, const int size) {
        // 创建一个指针变量p,初始化为指向数组的第一个元素
        const int *p = arr; // 空白1
    
        printf("数组元素为: ");
        // 循环size次
        for (int i = 0; i < size; i++) {
            // 通过指针p打印当前指向的元素
            printf("%d ", *p); // 空白2
    
            // 将指针p移动到下一个元素的位置
            p = p + 1; // 空白3
        }
        printf("\n");
    }
    
    int main() {
        int test_arr[] = {5, 10, 15, 20, 25};
        int size = sizeof(test_arr) / sizeof(test_arr[0]); // 计算数组元素个数
    
        print_array(test_arr, size); // 调用函数打印数组
    
        return 0;
    }
    

    小挑战: a)

    for (int i = 0; i < size; i++) {
        // 或者*(p + i)
        printf("%d ", p[i]); 
    }
    

    b) 会从 arr [2] 输出

    15 20 25
    
  5. 代码如下:

    #include <stdio.h>
    
    int main() {
        // 声明int和double变量
        int intValue = 42;
        double doubleValue = 3.14159;
    
        // 声明void指针
        void* ptr;
    
        // 让void指针指向int变量并打印值
        ptr = &intValue;
        printf("int值: %d\n", *(int*)ptr);
    
        // 让void指针指向double变量并打印值
        ptr = &doubleValue;
        printf("double值: %f\n", *(double*)ptr);
    
        return 0;
    }
    

    注意:使用 void* 指针时,必须将其转换为正确的类型后才能解引用,否则会导致未定义行为。这就是为什么在打印前需要先进行类型转换。

命令提示符@CommandPrompt-Wang
作者
命令提示符@CommandPrompt-Wang