寒假作业Day 08

文章详细解释了C语言中const和#define常量的区别,预处理指令的作用,以及编译流程。同时通过编程题展示了数组和指针在统计英文字符、空格和数字的使用上的应用。
摘要由CSDN通过智能技术生成

寒假作业Day 08

一、选择题

1、下列关于 const 和 #define 定义常量的区别,说法不正确的有( )
A: define宏是在预处理阶段展开。const常量是编译运行阶段使用
B: 宏没有类型,不做任何类型检查,仅仅是展开。const常量有具体的类型,在编译阶段会执行类型检查
C: define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。const常量会在内存中分配(可以是堆中也可以是栈中)
D: const定义和#define定义的常量在程序运行过程中只有一份拷贝

A: define宏是在预处理阶段展开。const常量是编译运行阶段使用
这个说法是不完全正确的。#define宏确实是在预处理阶段展开,但是const常量并不是在编译运行阶段使用,而是在编译阶段就已经确定了其值,并且在运行时是不可变的。所以,A选项中的“编译运行阶段使用”是不准确的。

B: 宏没有类型,不做任何类型检查,仅仅是展开。const常量有具体的类型,在编译阶段会执行类型检查
这个说法是正确的。#define宏只是简单的文本替换,没有类型,也不做类型检查。而const常量是有类型的,并且在编译阶段会进行类型检查。

C: define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。const常量会在内存中分配(可以是堆中也可以是栈中)
这个说法也是正确的。宏在预处理阶段会根据其在代码中的使用次数进行展开,并且不会分配内存。而const常量确实会在内存中分配存储空间,具体是在栈中还是堆中取决于其定义的位置和方式。

D选项说的是:“const定义和#define定义的常量在程序运行过程中只有一份拷贝。” 这个说法中,“const定义在程序运行过程中只有一份拷贝”是正确的,因为const常量在内存中确实有唯一的存储空间。但是,将#define宏与const常量相提并论,并说它们都有一份拷贝是不准确的,因为#define宏只是文本替换,并没有在内存中分配存储空间。

在这里插入图片描述

这个宏接收两个参数 x ,y,如果在上述声明之后,你把 Mul(x,y) 置于程序中,预处理器就会⽤下⾯这个表达式替换上⾯的表达式:++x*++y
a+b=3,b+c=5,++(a+b)*++(b+c)=++3 * ++5,即4 *6=24
大家是不是以为是这样的,但实际上,当我们使用编译器编译,我们会发现,最后的答案却为14,这是为什么呢?
其实真正的带入是这样子的:++a + b * ++b + c=2+3 * 3+3=14(++的优先级更高)

在这里插入图片描述

对于上述关于预编译和编译的说法,我们可以逐一分析:
A: C语言由源代码生成的各阶段如下,C源程序-编译预处理-编译-优化程序-汇编程序-链接程序-可执行文件
这个说法是正确的。C语言源代码首先经过预处理器处理,包括宏替换、条件编译等;然后经过编译器编译成汇编代码;接着汇编器将汇编代码转换成机器代码;最后链接器将多个目标文件(包括库文件)链接成一个可执行文件。

B: 常见的预编译指令有#include,#define,#if、#else和#endif
这个说法也是正确的。这些确实是C语言中常见的预处理指令。

C: 编译程序可以识别一些特殊的符号,比如__LINE__ ,表示当前行号的整数,这些是在编译阶段处理的
这个说法不完全准确。__LINE__这样的预定义宏是在预处理阶段处理的,而不是编译阶段。预处理阶段会替换这些宏为相应的值(例如当前源代码行号)。

D: #define定义宏,可以多次使用
这个说法是正确的。#define是C语言中的预处理指令,用于定义宏,宏可以在代码中多次使用,并在预处理阶段被替换为其定义的值或表达式。

在这里插入图片描述

A: 预处理命令行必须使用分号结尾
这是不正确的。预处理命令行(如#include, #define等)后面不需要分号。分号是在C语言源代码中用来表示语句结束的,而预处理命令行并不是C语言的语句。

B: 凡是以#号开头的行,都被称为编译预处理命令行
这是正确的。在C语言中,任何以#开头的行都被视为预处理指令或预处理命令行。这些行在编译的预处理阶段被处理。

C: 预处理命令行不能出现在程序的最后一行
这是不正确的。预处理命令行可以出现在程序的任何位置,包括最后一行。只要它们是有效的预处理指令,编译器就会在预处理阶段对它们进行处理。

D: 预处理命令行的作用域是到最近的函数结束处
这也是不正确的。预处理命令行的作用域通常是全局的,它们在整个源文件中都有效,而不是仅限于最近的函数结束处。例如,使用#define定义的宏可以在整个源文件中使用,而不仅仅是定义它的那个函数。

在这里插入图片描述

在main函数开始执行时,a已经被定义为10,所以在main函数中的第一个printf语句会输出10…。

接下来调用foo函数。在foo函数中,a的原始定义(10)被#undef取消了,然后a被重新定义为50。但是,请注意,#undef和#define指令在foo函数中的修改不会影响到main函数中a的值,因为预处理器指令的修改是全局的,但是它们的修改在预处理阶段就已经确定,并且不会随着函数的调用而改变。

当foo函数返回后,main函数中的第二个printf语句继续执行,此时a的值仍然是10,因为在预处理阶段a的值就已经确定为10了,即使foo函数中进行了重新定义,也不会影响到main函数中a的值。

二、编程题

在这里插入图片描述

#include <stdio.h>

int main() {
	//首先把1~100000的值都存储到数组里,以便之后使用
    int a[100000] = {0};
    a[0] = 1;
    a[1] = 2;
    for (int i = 2; i < 100000; i++) {
        a[i] = 2 * a[i - 1] + a[i - 2];//这是数值规律
        a[i] %= 32767;//每次都模一个32767防止数值溢出
    }

    int n = 0;
    scanf("%d", &n);
    while (n--) {
        int k = 0;
        scanf("%d", &k);
        printf("%d\n", a[k - 1]);//因为数组从0下标开始
    }
    return 0;
}

在这里插入图片描述

方法一:用for循环

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

int main() {
    char arr[1000] = {0};
    int count_English = 0;
    int count_Space = 0;
    int count_Number = 0;
    int count_Else = 0;
    gets(arr);
    int len=strlen(arr);
    for(int i=0;i<len;i++) {
        if (arr[i] >= 'a' && arr[i]<= 'z' || arr[i] >= 'A' && arr[i] <= 'Z') {
            count_English++;
        }

        else if (arr[i] == ' ') {
            count_Space++;
        }

        else if (arr[i] >= '0' && arr[i] <= '9') {
            count_Number++;
        }

        else {
            count_Else++;
        }
    }
    printf("%d\n%d\n%d\n%d\n", count_English, count_Space, count_Number, count_Else);
    return 0;
}

方法二:用while循环

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

int main() {
    char arr[1000] = {0};
    char* p=arr;
    int count_English = 0;
    int count_Space = 0;
    int count_Number = 0;
    int count_Else = 0;
    gets(arr);
    while(*p) {
        if (*p >= 'a' && *p <= 'z' || *p >= 'A' && *p <= 'Z') {
            count_English++;
        }

        else if (*p == ' ') {
            count_Space++;
        }

        else if (*p >= '0' && *p <= '9') {
            count_Number++;
        }

        else {
            count_Else++;
        }
        p++;
    }
    printf("%d\n%d\n%d\n%d", count_English, count_Space, count_Number, count_Else);
    return 0;
}

两者的区别在于一个用指针,一个用数组下标,其实核心方法都是一个样子

《淘淘商城-day08.docx》是一份关于淘淘商城第八天工作的文档。在这一天,淘淘商城的团队采取了一系列措施来进一步提升用户体验和销售业绩。 首先,团队进行了网站内容的优化。他们对商品详情页进行了修复和更新,确保信息的准确性和完整性。同时,他们也对页面的布局进行了调整,使得用户更容易浏览和购买商品。这些改进措施能够提升用户的满意度和购买转化率。 其次,团队还加强了与供应商的合作关系。他们与一些热门品牌建立起了合作伙伴关系,以获得独家销售权或更优惠的价格。这不仅能够吸引更多的用户,还能提高淘淘商城的竞争力。 另外,团队还对物流配送进行了优化。他们与一家可靠的物流公司合作,以确保商品能够及时、安全地送达给用户。他们还推出了更快速、更便捷的配送选项,如次日达和晚间配送,以满足用户的各种需求。 为了增加用户的复购率,团队还积极进行了促销活动。他们推出了限时限量的特价商品,以及购买一定金额就能获得赠品或折扣的优惠活动。这些促销措施能够吸引用户重复购买,并提升销售额。 总之,《淘淘商城-day08.docx》记录了淘淘商城团队在第八天所做的一系列工作。通过网站内容优化、供应商合作、物流配送优化和促销活动,团队致力于提升用户体验和销售业绩,从而使淘淘商城更加竞争和成功。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值