程序设计基础期末复习
程序设计基础期末复习
图文作业题汇总+ai解析
期末复习因为没有往年卷做现在闲得无聊导致的🤓
- 下面是几种不一样的二维数组的定义方式:
1 typedef int A[10];A p[10];
2 int** q=new int*[10]; for(int i=0;i<10;i++){q[i]=new int[10];};
3 int a[10][10];
4 int (*p)[10]=new int[m][10];(注意多维数组除了第一个可以是变量,其他都必须是常量);
那么区别在哪里?
1.memory allocation:第二、四个是动态数组(dynamic allocated);其他两个都是静态的数组(statically allocated); 一三四的内存是连续分配的,第二个每个一维数组不一定是连续存储的,但是每一个一维数组内部是连续的;
2.虽然都可以用p[i][j]来访问数组,但是本质不一样;一二四是*(*(arr+i)+j),第三个是 *(arr+i*m+j) 期中m是一维数组的长度;
3.一和四的联系:p其实就是A*类型的指针;
4.在撤销动态变量的时候,第四个只需要撤销一次即可:delete[] p;但是第二个需要先撤销每一行的数组,然后再撤销最外层;
作业14
一、简答题
单链表中,增加一个头结点的目的为?
- 答案:增加头结点可以简化链表的操作,尤其是在插入和删除操作时,无需特别处理链表的第一个节点。头结点不存储实际数据,它的存在使得链表操作更加统一,避免了空链表的特殊情况处理。
给定一个单链表,如何在遍历一次的情况下找到链表的中间节点?请描述算法的逻辑。
- 答案:使用快慢指针法。定义两个指针,一个快指针(每次移动两步)和一个慢指针(每次移动一步)。当快指针到达链表末尾时,慢指针正好指向链表的中间节点。
在以下代码中,p 和 q 的含义分别是什么?它们的操作有何不同?
int a[10]; int *p = &a[0]; int (*q)[10] = &a;
- 答案:
p
是一个指向int
类型的指针,指向数组a
的第一个元素。q
是一个指向包含 10 个int
类型元素的数组的指针,指向整个数组a
。- 操作不同:
p
可以用于遍历数组的每个元素,而q
用于操作整个数组。
- 答案:
简述动态分配二维数组时分配和释放内存的操作步骤。
- 答案:
- 分配内存:
int **arr = (int **)malloc(rows * sizeof(int *)); for (int i = 0; i < rows; i++) { arr[i] = (int *)malloc(cols * sizeof(int)); }
- 释放内存:
for (int i = 0; i < rows; i++) { free(arr[i]); } free(arr);
- 分配内存:
- 答案:
什么是函数指针?请简述函数指针的作用及其应用场景。
- 答案:
- 函数指针:函数指针是指向函数的指针变量,它存储了函数的地址。
- 作用:函数指针可以用于回调函数、动态函数调用等场景。
- 应用场景:事件处理、排序算法中的比较函数、插件机制等。
- 答案:
引用类型与指针类型的主要区别是什么?在以下场景中,哪个更适合使用指针?哪个更适合使用引用?
- 答案:
- 主要区别:
- 引用是变量的别名,必须在声明时初始化,且不能改变引用的对象。
- 指针是一个变量,存储的是另一个变量的地址,可以改变指向的对象。
- 场景选择:
- 修改传入的参数值:引用更适合,因为引用语法更简洁。
- 链表操作:指针更适合,因为链表操作需要频繁改变指向的对象。
- 遍历数组:引用和指针都可以,但指针更常见。
- 主要区别:
- 答案:
指针数组与二维数组在使用上有哪些相似之处?它们在内存布局上有何不同?
- 答案:
- 相似之处:都可以用于表示二维数据,访问元素时都可以使用双重下标。
- 内存布局不同:
- 二维数组是连续的内存块,所有元素按行优先顺序存储。
- 指针数组的每个元素是一个指针,指向不同的内存块,这些内存块可以不连续。
- 答案:
运行以下的代码并给出答案。
#include <iostream> using namespace std; int main() { // 定义一个二维数组 int arr[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 定义一个指针数组 int arr1[4] = {3, 1, 2, 3}; // 第一个元素代表当前数组的元素个数 int other[4] = {1,2,3,4}; // 一些无关的定义 int arr2[5] = {4, 4, 5, 6, 7}; int* ptrArr[2] = {arr1, arr2}; // 输出二维数组内容和地址 cout << "二维数组内容和地址:" << endl; for (int i = 0; i < 2; ++i) { for (int j = 0; j < 3; ++j) { cout << "arr[" << i << "][" << j << "] = " << arr[i][j] << ", 地址: " << &arr[i][j] << endl; } } // 输出指针数组内容和地址 cout << "\n指针数组内容和地址:" << endl; for (int i = 0; i < 2; ++i) { cout << "ptrArr[" << i << "] = " << ptrArr[i] << ", 地址: " << &ptrArr[i] << endl; int jnum = *(ptrArr[i]); for (int j = 1; j <= jnum; ++j) { cout << "ptrArr[" << i << "][" << j << "] = " << *(ptrArr[i] + j) << ", 地址: " << (ptrArr[i] + j) << endl; } } return 0; }
- 答案:
- 二维数组内容和地址:输出二维数组的每个元素及其地址。
- 指针数组内容和地址:输出指针数组的每个指针及其指向的数组元素及其地址。
- 答案:
二、选择题
对数组
int a[2][3]
的第i
行第j
列元素地址的引用正确的是()- 答案:D、
a[i]+j
- 答案:D、
以下声明指针数组的是()
- 答案:A、
int *p[2];
和 C、typedef int *ptr; ptr p[2];
- 答案:A、
有
int a[10]={1,2,3,4,5,6,7,8,9,10},*p=&a[3],b; b=p[5];
b
的值是()- 答案:D、9
有以下程序,输出结果是()
#include<stdio.h> int main() { int a=1, b=3, c=5; int *p1=&a, *p2=&b, *p=&c; *p=*p1 *(*p2); printf("%d\n", c); return 0; }
- 答案:C、3
三、编程题(选做)
作业
一、简答题
分别简述链表和数组的优点、缺点。请思考如何将链表的优点和缺点结合起来。
- 答案:
- 数组的优点:随机访问效率高,内存连续,缓存友好。
- 数组的缺点:插入和删除效率低,大小固定。
- 链表的优点:插入和删除效率高,动态扩展方便。
- 链表的缺点:随机访问效率低,内存不连续。
- 结合:可以使用块状链表(如块状数组或跳表),将链表和数组的优点结合起来。
- 答案:
描述链表的插入操作,并简要说明插入到链表头部、尾部和中间位置的不同实现。
- 答案:
- 头部插入:将新节点的
next
指向当前头节点,然后更新头节点为新节点。 - 尾部插入:遍历链表找到尾节点,将尾节点的
next
指向新节点。 - 中间插入:找到插入位置的前驱节点,将新节点的
next
指向前驱节点的next
,然后将前驱节点的next
指向新节点。
- 头部插入:将新节点的
- 答案:
请简述如何反转一个单链表?
- 答案:使用三个指针
prev
、curr
和next
,遍历链表,逐个反转节点的next
指针,最后更新头节点为原链表的尾节点。
- 答案:使用三个指针
对于单链表和数组,在不同的位置插入数据时,他们的效率有区别吗?
- 答案:
- 数组:头部插入 O(n),尾部插入 O(1),中间插入 O(n)。
- 链表:头部插入 O(1),尾部插入 O(n),中间插入 O(n)。
- 答案:
在块状链表中,如何高效查询一个元素?相比于普通链表,块状链表在查询时有哪些优势?
- 答案:先定位块,再在块内使用二分查找。查询时间复杂度为 O(√n),比普通链表的 O(n) 更高效。
二、选择题
已知头指针
h
指向一个非空单循环链表,结点结构为(data,next)
,其中next
是指向直接后继结点的指针,p
是尾指针,q
是临时指针。现要删除该链表的第一个元素,正确的语句序列是()。- 答案:D、
q=h; h=q->next; if (p==q) p=h; free(q);
- 答案:D、
在一个长度为
n
的单链表h
上,设有尾指针r
,则执行()操作与链表的表长有关。- 答案:B、删除单链表中的最后一个元素
已知一个双向链表
L
,结点结构为(prev,data,next)
,其中prev
和next
分别是指向其直接前驱和直接后继结点的指针。假设指针p
所指节点的前驱和后继节点均不为空,现要删除指针p
所指的结点,正确的语句序列是()。- 答案:D、
p->next->prev=p->prev; p->prev->next=p->next; free(p);
- 答案:D、
三、改错题
以下是一个实现单链表插入操作的代码,其中存在若干错误,请找出并修正这些错误。
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
void insertAtEnd(struct Node* head, int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
struct Node* current = head;
// 错误1:如果链表为空,head为NULL,current->next会引发段错误
if (head == NULL) {
head = newNode; // 错误2:head是局部变量,修改不会影响外部
return;
}
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
void printList(struct Node* head) {
struct Node* temp = head;
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
int main() {
struct Node* head = NULL;
insertAtEnd(head, 10); // 错误3:head未更新
insertAtEnd(head, 20);
insertAtEnd(head, 30);
printList(head);
return 0;
}
修正后的代码:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
void insertAtEnd(struct Node** head, int value) { // 修改为指向指针的指针
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
if (*head == NULL) {
*head = newNode; // 直接修改头指针
return;
}
struct Node* current = *head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
void printList(struct Node* head) {
struct Node* temp = head;
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
int main() {
struct Node* head = NULL;
insertAtEnd(&head, 10); // 传递头指针的地址
insertAtEnd(&head, 20);
insertAtEnd(&head, 30);
printList(head);
return 0;
}
四、编程题(选做)
约瑟夫问题:
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
int josephus(int n, int m) {
// 创建循环链表
Node* head = new Node{1, nullptr};
Node* curr = head;
for (int i = 2; i <= n; i++) {
curr->next = new Node{i, nullptr};
curr = curr->next;
}
curr->next = head; // 形成环
// 开始淘汰
while (curr->next != curr) {
// 找到第 m-1 个节点
for (int i = 1; i < m; i++) {
curr = curr->next;
}
// 删除第 m 个节点
Node* temp = curr->next;
curr->next = temp->next;
delete temp; // 释放内存
}
// 输出最后剩下的人的编号
int result = curr->data;
delete curr;
return result;
}
int main() {
int n = 5, m = 2;
cout << "最后剩下的人的编号是:" << josephus(n, m) << endl;
return 0;
}
输出结果:
最后剩下的人的编号是:3
希望这次的整合对你有帮助!如果还有其他问题,欢迎随时提问!
#作业12
指针的定义
在C/C++语言中,指针是什么?它在程序中有哪些作用?
- 指针:指针是一个变量,它存储的是另一个变量的内存地址。
- 作用:
- 动态内存分配(如
malloc
、new
)。 - 函数参数传递(如传递数组或大型结构体)。
- 实现数据结构和算法(如链表、树)。
- 直接访问硬件或内存地址。
- 动态内存分配(如
请说出以下段代码段中的定义,哪些是指针,指针的类型是什么。你能总结出指针定义的规律吗?
int *a1, a2; auto s = "hello"; auto ch = 'h'; int *a[20]; int (*a)[20];
- 指针及其类型:
int *a1
:a1
是指针,类型是int*
。auto s = "hello"
:s
是指针,类型是const char*
(字符串字面量的类型)。int *a[20]
:a
是指针数组,数组的每个元素是int*
类型。int (*a)[20]
:a
是指针,指向一个包含 20 个int
元素的数组,类型是int(*)[20]
。
- 指针定义的规律:
type *name
:定义一个指向type
类型的指针。type *name[size]
:定义一个数组,数组的每个元素是指向type
类型的指针。type (*name)[size]
:定义一个指针,指向一个包含size
个type
类型元素的数组。
- 指针及其类型:
指针间接访问
请将以下的函数改写成等价的使用指针间接访问的形式
int index(int *a, int i) { return a[i]; }
- 改写:
int index(int *a, int i) { return *(a + i); }
- 改写:
请将以下代码片段用指针改写成更加简洁的形式
if (i == 0) { a = 3 * x * x + x * 2 + x / 9 + x >> 8 * 10000; } else if (i == 1) { b = 3 * x * x + x * 2 + x / 9 + x >> 8 * 10000; } else if (i == 2) { c = 3 * x * x + x * 2 + x / 9 + x >> 8 * 10000; } else if (i == 3) { d = 3 * x * x + x * 2 + x / 9 + x >> 8 * 10000; } else if (i == 4) { e = 3 * x * x + x * 2 + x / 9 + x >> 8 * 10000; }
- 改写:
int *arr[] = {&a, &b, &c, &d, &e}; if (i >= 0 && i < 5) { *arr[i] = 3 * x * x + x * 2 + x / 9 + x >> 8 * 10000; }
- 改写:
指针与函数
以地址传递参数和以值传递参数的优点和缺点分别是什么?如何针对缺点进行改进?
- 地址传递:
- 优点:避免数据拷贝,效率高;可以修改实参的值。
- 缺点:可能引入指针安全问题(如空指针、野指针)。
- 改进:使用
const
修饰指针,避免意外修改。
- 值传递:
- 优点:安全,不会修改实参的值。
- 缺点:数据拷贝开销大,尤其是大型结构体或数组。
- 改进:对于大型数据,使用引用或指针传递。
- 地址传递:
以地址传递参数一定比以值传递参数效率高吗?有没有例外?
- 不一定。如果传递的数据很小(如基本类型),值传递可能更高效,因为指针本身也有开销。
指针常量
请分别解释以下几种指针的定义分别表示什么意思,有什么区别。
int* const a, b; const int* a, b; int const* a, b; const int* const a; int const* const a; int *const* a;
- 解释:
int* const a
:a
是一个常量指针,指向int
类型,指针的地址不能改变,但指向的值可以改变。const int* a
和int const* a
:a
是指针,指向const int
类型,指针的地址可以改变,但指向的值不能改变。const int* const a
和int const* const a
:a
是一个常量指针,指向const int
类型,指针的地址和指向的值都不能改变。int *const* a
:a
是指针,指向int* const
类型,即指向一个常量指针。
- 解释:
当在函数的参数中传递指针时,如果使用常量指针如
const int *a
作为参数,那么其对函数内的程序有怎么样的约束?对函数的调用者提供怎么样的保证?- 约束:函数内不能通过指针修改指向的值。
- 保证:调用者知道函数不会修改传入的数据。
当在函数的返回值中传递指针时,如果返回常量指针如
const int *
,那么其对函数的调用者有什么样的约束?- 约束:调用者不能通过返回的指针修改指向的值。
如果一个函数接受字符串作为参数,而不需要修改原字符串,使用
const char*
作为参数相比char *
有什么好处?- 好处:
- 明确表示函数不会修改字符串内容。
- 可以接受常量字符串(如
"hello"
)作为参数,避免编译错误。
- 好处:
作业12:枚举类型
1. 请解释C++中的enum类型,并说明它与普通整数类型的区别。请举例说明如何定义和使用一个enum类型,并解释为什么在某些情况下使用enum类型比使用普通整数类型更合适。
- enum类型:
enum
是C++中的枚举类型,用于定义一组命名的整数常量。它可以将一组相关的常量值组织在一起,提高代码的可读性和可维护性。 - 与普通整数类型的区别:
enum
类型是强类型的,不能直接与整数混用(除非显式转换)。enum
类型的值是有意义的名称,而普通整数类型的值是无意义的数字。
- 定义和使用:
enum Color { RED, GREEN, BLUE }; // 定义枚举类型 Color c = GREEN; // 使用枚举类型 if (c == GREEN) { cout << "The color is green!" << endl; }
- 使用
enum
的优势:- 提高代码可读性:使用有意义的名称代替无意义的数字。
- 避免魔法数字:减少代码中直接使用数字的情况。
- 类型安全:避免错误的赋值或比较。
2. 请查阅资料了解一下C++11引入的enum class,并简述它与课堂上的enum类型的区别和优势。
enum class
:C++11 引入了enum class
,它是一种作用域枚举类型。- 区别和优势:
- 作用域:
enum class
的枚举值在枚举类型的作用域内,不会污染全局命名空间。 - 强类型:
enum class
不能隐式转换为整数,必须显式转换。 - 底层类型:可以指定底层类型(如
enum class Color : char
)。 - 示例:
enum class Color { RED, GREEN, BLUE }; Color c = Color::GREEN; if (c == Color::GREEN) { cout << "The color is green!" << endl; }
- 作用域:
结构类型
1. 判断题:
结构体成员的类型必须是基本数据类型。
- 答案:错误。结构体成员可以是任意类型,包括数组、指针、其他结构体等。
一个结构类型变量所占的内存空间是其各个成员所占内存空间之和。
- 答案:错误。结构体的内存空间可能包含对齐填充(padding),因此不一定等于成员大小之和。
下面这个代码中,
per
是结构体变量名。typedef struct { int n; char ch[8]; } per;
- 答案:错误。
per
是结构体类型的别名,不是变量名。
- 答案:错误。
2. 观察下面代码,指出代码中存在的错误:
#include <iostream>
#include <string>
using namespace std;
enum Major {
MATHEMATICS,
PHYSICS,
COMPUTER, // 错误1:缺少分号
};
struct UndergraduateStudent {
char name[20];
double grade;
Major major;
}; // 错误2:缺少分号
struct GraduateStudent {
char name[20];
double grade;
Major major;
}; // 错误3:缺少分号
int main() {
UndergraduateStudent s1 = {'A', 93.7, 0}; // 错误4:'A' 是字符,不能初始化字符数组
GraduateStudent s2 = {"B", 70.0, COMPUTER}; // 正确
UndergraduateStudent s3 = s2; // 错误5:类型不匹配,不能将 GraduateStudent 赋值给 UndergraduateStudent
return 0;
}
3. (选做)深入探索Struct内存布局
代码1:
#include <iostream>
struct {
unsigned char b1 : 10;
unsigned char b2 : 6;
unsigned char b3 : 16;
} S;
int main() {
std::cout << sizeof(S) << '\n';
}
代码2:
#include <iostream>
struct {
unsigned char b1 : 10;
unsigned char b2 : 16;
unsigned char b3 : 6;
} S;
int main() {
std::cout << sizeof(S) << '\n';
}
分析:
- 代码1:
b1
占用 10 位,b2
占用 6 位,共 16 位(2 字节)。b3
占用 16 位(2 字节)。- 总大小为 4 字节。
- 代码2:
b1
占用 10 位,b2
占用 16 位,无法放在同一字节中,因此b1
和b2
分别占用 2 字节和 2 字节。b3
占用 6 位,单独占用 1 字节。- 总大小为 5 字节。
验证方案:
- 使用
sizeof
输出结构体大小,验证分析结果。
联合类型
1. 结构类型变量和联合类型变量分别适合应用在什么场景?它们的内存布局由哪些因素决定?
- 结构体:
- 场景:用于存储一组相关的数据,每个成员有独立的内存空间。
- 内存布局:由成员的顺序、大小和对齐方式决定。
- 联合体:
- 场景:用于存储一组可能的数据类型,但同一时间只能使用其中一个成员。
- 内存布局:所有成员共享同一块内存,大小为最大成员的大小。
2. (选做)利用联合类型判断系统是大端模式还是小端模式。
#include <iostream>
union EndianTest {
int value;
char bytes[sizeof(int)];
};
int main() {
EndianTest test;
test.value = 0x01020304;
if (test.bytes[0] == 0x04) {
std::cout << "Little endian" << std::endl;
} else {
std::cout << "Big endian" << std::endl;
}
return 0;
}
解释:
- 在小端模式下,低字节存储在低地址,因此
test.bytes[0]
是0x04
。 - 在大端模式下,高字节存储在低地址,因此
test.bytes[0]
是0x01
。
数组
1. 请说明C、C++中对多维数组的内存安排,并尝试讨论这样做的优劣。
内存安排:
- 在C/C++中,多维数组在内存中是按行优先顺序(Row-major order)存储的。
- 例如,二维数组
int arr[2][3]
的内存布局为:arr[0][0]
,arr[0][1]
,arr[0][2]
,arr[1][0]
,arr[1][1]
,arr[1][2]
。 - 对于更高维的数组,内存布局也是类似的,从最外层维度到最内层维度依次展开。
优劣:
- 优点:
- 内存连续,缓存友好,访问效率高。
- 可以通过指针算术直接访问任意元素。
- 缺点:
- 多维数组的大小固定,灵活性较差。
- 动态分配多维数组时,代码较为复杂。
- 优点:
2. 计算 arr[1][2][3][4][5]
的地址
给定五维数组 int arr[2][3][4][5][6]
,起始地址为 0x1000
,每个整数占用 4 字节。
计算公式:
地址 = 基地址 + (i1 * S1 + i2 * S2 + i3 * S3 + i4 * S4 + i5) * sizeof(int) 其中: S1 = 3 * 4 * 5 * 6 S2 = 4 * 5 * 6 S3 = 5 * 6 S4 = 6
计算过程:
S1 = 3 * 4 * 5 * 6 = 360 S2 = 4 * 5 * 6 = 120 S3 = 5 * 6 = 30 S4 = 6 地址 = 0x1000 + (1 * 360 + 2 * 120 + 3 * 30 + 4 * 6 + 5) * 4 = 0x1000 + (360 + 240 + 90 + 24 + 5) * 4 = 0x1000 + 719 * 4 = 0x1000 + 2876 = 0x1000 + 0xB3C = 0x1B3C
最终地址:
0x1B3C
字符串
1. 描述字符串的各种初始化方式
示例1:
char str[10] = {'h', 'e', 'l', 'l', 'o', '\0'};
- 初始化一个长度为 10 的字符数组,前 6 个字符为
'h', 'e', 'l', 'l', 'o', '\0'
,剩余部分填充\0
。
- 初始化一个长度为 10 的字符数组,前 6 个字符为
示例2:
char str[5] = {'h', 'e', 'l', 'l', 'o'};
- 初始化一个长度为 5 的字符数组,没有
\0
结尾,因此不是合法的 C 字符串。
- 初始化一个长度为 5 的字符数组,没有
示例3:
char str[] = "hello";
- 初始化一个长度为 6 的字符数组,包含
'h', 'e', 'l', 'l', 'o', '\0'
。
- 初始化一个长度为 6 的字符数组,包含
示例4:
char str[5] = "hello";
- 初始化一个长度为 5 的字符数组,但字符串
"hello"
需要 6 个字符(包括\0
),因此会截断\0
,导致不是合法的 C 字符串。
- 初始化一个长度为 5 的字符数组,但字符串
示例5:
char str[5]; str[0] = '0';
- 声明一个长度为 5 的字符数组,未初始化,仅将第一个字符设置为
'0'
。
- 声明一个长度为 5 的字符数组,未初始化,仅将第一个字符设置为
2. 描述 strncpy
的行为
strncpy
的定义:char *strncpy(char *dest, const char *src, size_t n);
- 将
src
的前n
个字符复制到dest
中。
- 将
行为:
- 如果
src
的长度小于n
,则dest
剩余部分填充\0
。 - 如果
src
的长度大于或等于n
,则dest
不会以\0
结尾。
- 如果
3. (选做)实现查找子串的函数(strstr
)
const char *my_strstr(const char *str, const char *substr) {
if (*substr == '\0') return str;
for (const char *p = str; *p != '\0'; p++) {
const char *s1 = p;
const char *s2 = substr;
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) {
s1++;
s2++;
}
if (*s2 == '\0') return p;
}
return nullptr;
}
枚举类型
1. 枚举类型和整数类型有什么关系?在参与运算时,关于枚举类型有哪些运算规则?
关系:
- 枚举类型的底层是整数类型,每个枚举值对应一个整数常量。
- 默认情况下,第一个枚举值为
0
,后续枚举值依次递增。
运算规则:
- 枚举值可以隐式转换为整数,但整数不能隐式转换为枚举类型。
- 枚举值可以参与整数运算,但结果仍然是整数类型。
2. 观察下面代码,写出这个枚举类型中每个成员的值,并说明这样定义是否存在问题?
enum Day {
SUNDAY = -1,
MONDAY = 3,
TUESDAY,
WEDNESDAY = 2,
THURSDAY,
FRIDAY,
SATURDAY
};
枚举值:
SUNDAY = -1 MONDAY = 3 TUESDAY = 4 WEDNESDAY = 2 THURSDAY = 3 FRIDAY = 4 SATURDAY = 5
问题:
THURSDAY
和MONDAY
的值相同(3
),FRIDAY
和TUESDAY
的值相同(4
),这可能导致逻辑错误。