本篇文章为《十天速通C语言基础(day04)》的内容补充。
目录
1.数组大小
#include <stdio.h>
int main(int argc, char const *argv[])
{
// 定义一个整型数组a1,包含5个元素,分别为5, 6, 7, 8, 9
int a1[5] = {5, 6, 7, 8, 9};
// 定义一个整型数组a2,包含3个元素,分别为2, 3, 5
int a2[5] = {2, 3, 5};
// 定义一个整型数组a3,不初始化,默认所有元素为0
int a3[5] = {};
// 定义一个整型数组a4,包含5个元素,分别为1, 2, 3, 4, 5
int a4[5] = {1, 2, 3, 4, 5};
// 输出数组a1的大小,即5个整数所占的字节数
printf("%d", sizeof(a1));
// 输出数组a2的大小,即5个整数所占的字节数(尽管只初始化了3个元素)
printf("%d", sizeof(a2));
// 输出数组a3的大小,即5个整数所占的字节数(所有元素都为0)
printf("%d", sizeof(a3));
// 输出数组a4的大小,即5个整数所占的字节数
printf("%d", sizeof(a4));
return 0;
}
这段代码主要展示了C语言中数组的基本概念和用法。以下是一些关键点:
数组的定义:在C语言中,可以使用
int a[5]
这样的语法来定义一个整型数组,其中a
是数组的名称,5
表示数组的大小(即可以存储的元素个数)。在这个例子中,我们定义了四个不同的数组,分别是a1
,a2
,a3
,a4
。数组的初始化:可以在定义数组时直接为其元素赋值,如
int a1[5] = {5, 6, 7, 8, 9};
。也可以只初始化部分元素,未初始化的元素将自动赋予默认值(对于整数类型,默认值为0)。
sizeof
运算符:sizeof
是一个编译时运算符,用于计算某个数据类型或对象所占用的字节数。在这个例子中,我们使用sizeof(a1)
来计算数组a1
的大小。由于每个整数占用4个字节(这取决于编译器和操作系统),所以sizeof(a1)
的结果将是20(5个整数乘以4)。输出结果:通过
printf
函数,我们将数组的大小以字节为单位打印出来。注意,这里的大小是指整个数组所占用的内存空间大小,而不是数组中实际存储的元素个数。
需要注意的是,尽管我们在定义数组时指定了大小为5,但实际上数组的大小是由其声明时指定的元素个数决定的。在这个例子中,尽管
a2
只初始化了3个元素,但它仍然占用与a1
相同的内存空间大小(20字节),因为数组的大小是在声明时就确定的。实际上,上述程序中的四个数组大小并不一样。每个数组的大小是由其声明时指定的元素个数决定的。以下是每个数组的大小:
a1
的大小为5个整数所占的字节数,即20字节(5 * 4)。a2
的大小也为5个整数所占的字节数,即20字节(尽管只初始化了3个元素,但其余两个元素默认值为0)。a3
的大小同样为5个整数所占的字节数,即20字节(所有元素都初始化为0)。a4
的大小为5个整数所占的字节数,即20字节。因此,虽然这四个数组在代码中都被声明为包含5个元素的数组,但由于它们各自初始化的元素个数不同,所以实际占用的内存空间大小是一样的。
2.清零函数
在C语言中,bzero
和memset
是两个用于处理内存的函数,它们可以用来将一段内存区域的内容设置为特定的值。这两个函数在清零操作(即将内存区域的字节设置为0)时特别有用,但它们的用途不仅限于此。
2.1bzero
bzero
函数是用于将指定内存区域的内容设置为零的函数,尽管它在一些旧式UNIX系统中很常见,但现在已经被认为过时,多数现代系统和标准推荐使用memset
函数替代。下面将详细讲述bzero
的运用和注意事项:
2.1.1bzero函数的定义和参数
bzero的函数原型为下方
void bzero(void *ptr, size_t size);
ptr
:指向要清零的内存块的指针。size
:要清零的字节数。bzero
函数将ptr
指向的内存块的前size
个字节设置为0。- 返回值:无
2.1.2bzero函数清零内存
- 需要包含头文件
string.h
,因为bzero
函数在该头文件中声明。- 定义一个内存区域的指针,并分配足够的内存空间。
- 调用
bzero
函数,将指定内存区域的内容全部设置为零。
2.1.3注意事项
- 在使用
bzero
函数之前,确保已经分配了足够的内存空间。这是为了避免未分配内存就进行操作,从而引发程序错误。bzero
函数在一些编译器中可能已经被废弃,建议使用更安全、标准的函数memset
来代替。- 需要确保传入的参数合法有效,避免出现指针错误或内存越界等问题。这是确保程序稳定性和安全性的关键措施。
2.1.4历史背景
bzero
起源于UNIX操作系统的开发,主要用于内存管理和初始化操作。它被设计为一种方便且快速的方式来清零内存块。然而,随着C语言标准的发展和POSIX标准的更新,bzero
被标记为遗留函数,不再推荐在新代码中使用。
2.2memset
memset
函数是C语言中用于操作内存的常用函数之一,其功能是将一段内存区域的内容设置为指定的值。下面将详细讲述其运用和注意事项:
2.2.1memset函数的定义和参数
memset
函数原型为下方:
void *memset(void *ptr, int value, size_t num);
ptr
:指向要填充的内存块的指针。value
:要设置的值。传递给函数的值会转换为unsigned char类型,然后用于设置内存块的内容。num
:要设置的字节数。memset
函数将ptr
指向的内存块的前num
个字节设置为value
。- 返回值:数组首地址
2.2.2使用memset函数初始化内存
- 需要包含头文件
string.h
,因为memset
函数在该头文件中声明。 - 定义一个内存区域的指针,并分配足够的内存空间。
- 调用
memset
函数,将指定内存区域的内容全部设置为特定值
2.2.3注意事项
- 在使用
memset
函数之前,确保已经分配了足够的内存空间。这是为了避免未分配内存就进行操作,从而引发程序错误。 memset
函数按字节对内存块进行初始化,所以不能用它将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同)。memset
的第二个参数value
实际范围应该在0到255之间,因为该函数只能取value
的低8位赋值给每个字节。- 确保传入的参数合法有效,避免出现指针错误或内存越界等问题。这是确保程序稳定性和安全性的关键措施。
- 避免过度使用
memset
。在某些情况下,过度使用会导致性能下降或不必要的操作。
2.3清零示例
如果你想使用memset
函数来清零一个内存块,你可以这样做:
#include <string.h>
int main() {
int array[5] = {1, 2, 3, 4, 5};
memset(array, 0, sizeof(array));
// 现在array的所有元素都为0
for (int i = 0; i < 5; i++) {
printf("%d ", array[i]); // 输出: 0 0 0 0 0
}
return 0;
}
在这个例子中,我们使用memset
函数将整型数组array
的所有元素设置为0。sizeof(array)
给出了整个数组的大小(以字节为单位),因此memset
会将整个数组的内容设置为0。
2.4总结
bzero
函数专用于清零内存块,但已被弃用,建议使用memset
替代。memset
函数更加通用,可以用于设置内存块为任意值,包括0。- 当你需要清零内存块时,推荐使用
memset
函数。
3.字符数组
字符数组是元素的数据类型为字符类型的数组在C语言中,字符数组是一种用于处理字符串和字符序列的数据结构。它由一系列字符组成,每个字符占用一个固定的位置,这些位置在内存中是连续的。字符数组可以用于表示文本数据,如单词、句子或更复杂的字符串。以下是一些关于C语言中字符数组的基本概念和使用方法:
3.1定义和初始化
逐个字符赋值
用字符串常量
字符数组可以在声明时初始化,也可以在后续的代码中赋值。这里有几种不同的定义和初始化方式:
C语言中无字符串变量,用字符数组处理字符串
字符串结束标志:‘\0’
1.直接初始化
char str1[] = "Hello, World!";
2.指定大小初始化
char str2[5] = "Hi"; // 剩余的字符将自动填充'\0'
3.未指定大小(自动大小)
char str3[] = "Goodbye"; // 编译器会自动计算大小
访问和修改
str1[0] = 'h'; // 修改第一个字符为小写
printf("%c", str1[3]); // 输出字符'l'
字符串操作
C语言提供了一系列标准库函数来处理字符串,包括:
strcpy(dest, src)
:将src
字符串复制到dest
。strcat(dest, src)
:将src
字符串连接到dest
字符串的末尾。strlen(str)
:返回字符串str
的长度。strcmp(str1, str2)
:比较两个字符串。strchr(str, ch)
:在字符串str
中查找字符ch
。
注意事项
- C语言中的字符串以空字符
\0
结束,这是字符串结束的标志。 - 数组的大小应该足够大以包含所有字符和终止字符
\0
。 - 当使用字符串函数时,确保目标数组有足够的空间来存储结果,以避免缓冲区溢出。
示例
#include <stdio.h>
#include <string.h>
int main() {
char greeting[20] = "Hello, ";
char name[] = "World!";
strcat(greeting, name); // 连接字符串
printf("%s
", greeting); // 输出 "Hello, World!"
return 0;
}
这个例子展示了如何使用strcat
函数将两个字符数组连接起来,并使用printf
函数输出结果。
注意:字符串" " 以'\0'结束,定义数组元素个数时,要把'\0'考虑上
3.2输入输出
3.2.1 for
for
循环是一种控制结构,用于在满足特定条件时重复执行一段代码。for
循环在输入输出操作中尤其常用,因为它可以方便地处理多次的输入输出操作,例如读取一系列数据或打印一定次数的信息。以下是使用for
循环进行输入输出的基本方法:
for
循环的基本结构
for (初始化表达式; 条件表达式; 更新表达式)
{
// 循环体(需要执行的代码)
}
- 初始化表达式:在循环开始前执行,通常用于设置循环控制变量的初始值。
- 条件表达式:在每次循环开始前判断,如果为真,则执行循环体;如果为假,则退出循环。
- 更新表达式:在每次循环结束后执行,通常用于更新循环控制变量的值。
使用for
循环进行输入输出
示例1:读取和打印一系列整数
假设我们要从用户那里读取5个整数,并打印它们:
#include <stdio.h>
int main() {
int numbers[5];
int i;
printf("Enter 5 integers: ");
for (i = 0; i < 5; i++) {
scanf("%d", &numbers[i]); // 读取一个整数并存储
}
printf("You entered: ");
for (i = 0; i < 5; i++) {
printf("%d ", numbers[i]); // 打印整数
}
return 0;
}
在这个例子中,我们使用两个for循环:
第一个循环读取5个整数
第二个循环打印这些整数
示例2:打印表格
假设我们要打印一个5行的文本表格:
#include <stdio.h>
int main() {
for (int i = 1; i <= 5; i++) {
printf("-------------------------------
");
printf("| This is row number %d |
", i);
printf("-------------------------------
");
}
return 0;
}
在这个例子中,
for
循环用于控制表格的行数,每行都打印相同的文本模式,但行号i
不同。
注意事项
- 确保循环条件和更新表达式的设置能够使循环在预期的次数后终止。
- 在循环体中正确使用索引变量,以避免访问数组或其他数据结构的边界之外。
- 在使用
scanf
函数读取数据时,确保提供正确的格式字符串和变量地址,以避免错误和潜在的安全问题。
for
循环是C语言中实现重复任务的强大工具,它使得处理序列和集合的数据变得更加简单和高效。
3.2.2 %s
在C语言中,%s
是用于读取和输出字符串的格式说明符。它与scanf
函数配合使用时可以从输入中读取字符串,而与printf
函数配合使用时可以输出字符串。下面将详细讲述其在输入输出中的应用:
- 输入字符串
char str[10]; scanf("%s", str);
会读取一个以空字符终止的字符串并存储到str
中。- 当使用
%s
格式时,遇到空格或换行符会停止读取,这意味着只会读取连续非空白字符。
- 输出字符串
char str[] = "Hello"; printf("%s", str);
会输出"Hello"
。- 在输出时,
printf
会从给定的地址开始,依次输出字符直到遇到第一个空字符('\0'
)为止。
使用%s
进行字符串输入输出时,需要注意的几个关键点:
- 数组长度:确保字符数组足够长以存储读取的字符串,包括终止字符
'\0'
。如果输入的字符串超过数组长度,会导致缓冲区溢出问题,这可能导致程序错误甚至崩溃。 - 字符串处理:在使用
%s
处理字符串时,不能处理含有空格的字符串。如果需要读取整行(包含空格),则应使用fgets
等其他函数。
综上所述,通过正确使用%s
格式说明符,可以在C语言中方便地进行字符串的输入输出操作。然而,必须小心处理字符串的长度和潜在的输入错误。
3.2.3 gets
gets
函数是C语言中用于从标准输入读取一行文字并存储到字符数组中的函数。
- 该函数原型为
char *gets(char *str)
- 功能:终端输入字符串
- 参数:字符数组首地址
- 返回值:字符数组首地址
其中str
是一个字符数组或字符指针。尽管gets
函数在读取字符串时较为方便,但它存在安全隐患,因此并不推荐使用,并在C11标准中被废弃。
gets
函数的工作原理是从标准输入(如键盘)读取字符直到遇到换行符或文件末尾,并将这些字符存储到指定的内存位置。它丢弃换行符,并在字符串末尾添加一个空字符('\0'
)来标记字符串的结束。然而,正因为gets
不进行缓冲区溢出检查,如果输入的数据长度超过了目标数组的长度,会导致内存安全问题。
3.2.4 puts
在C语言中,puts
函数用于将字符串输出到标准输出(通常是终端或屏幕),并在字符串的末尾自动添加一个新行字符。
- 该函数的原型是
int puts(const char *str)
- 其中
str
是一个指向要输出的字符串的指针。- 功能:终端输出字符串
- 参数:字符数组首地址
- 返回值:输出字符的个数
- 支持空格;puts自带换行功能
基本用法
puts
函数的使用方法非常简单。它接受一个字符串作为参数,并将其打印到标准输出,然后在字符串的末尾添加一个换行符。这使得 puts
在输出完整句子或独立的文本行时非常有用。
#include <stdio.h>
int main()
{
puts("Hello, World!");
return 0;
}
在这个简单的程序中,puts
函数被用来输出字符串 "Hello, World!" 到屏幕上,并且由于 puts
函数的特性,输出的字符串后面会自动加上一个换行符。
注意事项
- 空字符:
puts
函数会持续输出字符串中的字符,直到遇到空字符('\0')为止。因此,它只能用于输出以空字符终止的字符串。- 缓冲区:与
printf
不同,puts
不提供格式化输出的功能。如果需要格式化输出多变量或者进行特殊字符处理,应使用printf
函数。- 返回值:
puts
函数在成功时返回一个非负值,通常为输出的字符数。如果发生错误,它会返回EOF
(通常为 -1)。
3.3字符串实际元素个数
在C语言中,字符串被定义为字符的序列,包括可见字符以及不可见的空字符(null terminator),这个空字符标记着字符串的结束,并允许各种字符串操作函数知道字符串的终点在哪里。
字符串的实际元素个数
对于一个C语言中的字符串来说,如果我们说“实际元素个数”,我们通常指的是字符串中的可见字符数。然而,为了正确表示一个字符串,C语言实际上会在字符串的末尾添加一个额外的'\0'
(空字符)作为终止符。因此,如果我们谈论的是字符串的“长度”,有两种可能的含义:
- 字符串长度:不包括结尾的空字符。这是字符串中可见字符的数量,也是大多数字符串函数(如
strlen
)返回的值。 - 字符串占用空间:包括结尾的空字符。这是指字符串在内存中实际占用的字节数,总是比字符串长度多1。
示例
考虑字符串
"hello"
:
- 字符串长度是5,因为有五个可见字符('h', 'e', 'l', 'l', 'o')。
- 字符串占用空间是6,因为还包括了末尾的空字符('\0')。
计算字符串长度
使用C标准库中的strlen
函数,可以计算字符串的长度,即其中可见字符的数目:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "hello";
int length = strlen(str); // 结果是5
printf("String length is %d
", length);
return 0;
}
注意事项
- 当处理字符串时,始终记住预留一个额外的位置给末尾的空字符,特别是在分配字符串空间或复制字符串时。
- 使用字符串函数时,确保字符串是以空字符
'\0'
正确终止的,以避免出现未定义行为。
理解C语言中字符串的这些基本概念对于进行字符串操作和避免常见的编程错误至关重要。正确的处理字符串长度和其占用的空间有助于防止缓冲区溢出等安全问题。
3.4strlen
在C语言中,strlen
函数是一个非常重要的字符串处理函数,用于计算并返回一个字符串的长度。这个长度实际上是从字符串起点到第一个空字符('\0'
)之前的字符数。
strlen
函数原型如下size_t strlen(const char *str)
;- 其中
str
是指向字符串的指针。- 功能:计算字符串的实际元素个数
- 参数:字符数组的首地址
- 返回值:字符串实际元素个数
用法
strlen
函数的基本用法非常简单:它接受一个字符串作为输入参数,并返回该字符串的长度,即其中的字符数,不包括结尾的空字符。
示例代码:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
size_t length = strlen(str);
printf("The string '%s' has a length of %zu characters.
", str, length);
return 0;
}
在这个例子中,strlen(str)
将返回值 13
,因为 str
中包含 13
个可见字符(包括逗号和感叹号),但不包括结尾的空字符。
注意事项
- 空字符串:对于空字符串(一个或多个空字符构成的字符串),
strlen
返回0
。- 空指针:如果传递给
strlen
的是空指针(NULL
),结果是未定义的,通常会导致程序崩溃。因此,在调用strlen
之前应该检查字符串是否为NULL
。- 长字符串:对于非常长的字符串,
strlen
可能需要较多的时间来计算长度,因为它必须从字符串的起点开始,逐个字符地计数,直到遇到结束符。- 逻辑错误:有时可能会错误地认为
strlen
计算的是字节数,包括结尾的空字符。这是错误的理解,strlen
返回的是字符数,不包括结尾的空字符。- 性能考虑:在性能敏感的应用中,频繁调用
strlen
可能会影响性能。在这种情况下,可以通过缓存字符串长度的结果来避免重复计算。- 安全替代:在某些情况下,为了安全起见,可能需要使用诸如
strnlen
之类的替代函数,这些函数可以限制检查字符的数量,从而防止缓冲区溢出。
sizeof和strlen区别:
- sizeof是关键字,strlen是函数
- sizeof是计算元素开辟空间大小,strlen计算字符串实际元素个数
- sizeof的计算包含'\0';strlen的计算不包含'\0'
总的来说,strlen
是一个非常实用的C语言标准库函数,用于快速确定字符串的长度。然而,在使用它时,开发者需要注意其潜在的陷阱和性能问题,并采取适当的预防措施。
4.冒泡排序
冒泡排序是C语言中一种简单但效率较低的排序算法,它重复地走访过要排序的元素列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数轮后,较大或较小的元素会逐渐移向顶端或末端,就像气泡最终会上浮到水面一样,因此得名“冒泡排序”。
思路
- 比较相邻元素:从第一个元素开始,依次比较相邻的两个元素,如果前一个比后一个大(对于升序排列),则交换它们的位置。
- 重复步骤:对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这步完成后,最后的元素会是最大的元素。
- 再次重复:针对所有的元素重复以上的步骤,除了最后一个。
- 持续减少:持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
用法
以下是一个简单的C语言冒泡排序实现:
int a[5]={2,3,4,5,6},t;
for(int i=0;i<5-1;i++) //轮数
{
for(int j=0;j<5-1-i;j++) //每一轮比较次数
{
if(a[j]<a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
for(int i=0;i<5;i++)
printf("%d ",a[i]);
注意事项
- 效率问题:冒泡排序的时间复杂度为O(n^2),不适用于大数据集。
- 优化:可以通过增加标志位来优化,如果在一次遍历中没有发生任何交换,则数组已经排序完成,可以直接跳出循环。
- 稳定性:冒泡排序是稳定的排序算法,即相对位置相同的元素在排序后其顺序不会改变。
- 空间复杂度:由于是原地排序,空间复杂度为O(1)。
- 适应性:对于接近有序的数据集,可以进一步优化冒泡排序,使其更加高效。
5.选择排序
选择排序是一种简单直观的排序算法,其基本思想是重复地从待排序的元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部元素排序完毕。选择排序的主要优点是简单易懂,实现容易;缺点是效率较低,时间复杂度为O(n^2),因此不适用于大规模数据的排序。
思路
- 找到最小(或最大)元素:从头开始,找到数组中最小的元素,将其与数组的第一个元素交换位置。
- 缩小排序范围:在剩下的元素中继续寻找最小的元素,将其与数组的第二个元素交换位置。
- 重复此过程:重复上述步骤,每次从未排序的部分找出最小的元素,然后与未排序部分的第一个元素交换位置,直到整个数组排序完成。
用法
以下是一个简单的C语言选择排序实现:
int a[5]={2,5,4,3,12},min=0,t; //min暂存最小元素索引
for(int i=0;i<5-1;i++)
{
min=i; //假设最左边元素最小
for(int j=i+1;j<5;j++) //获取剩下的几个元素
{
if(a[min]>a[j]) //出现更小值时,索引更新
min=j;
} //循环结束,min是本轮循环的最小元素索引
//a[min] a[i] //要交换的是 最小元素 和 最左边位置
if(min!=i) //排除最左边要交换的位置=本轮最小元素的位置
{
t=a[min];
a[min]=a[i];
a[i]=t;
}
}
for(int i=0;i<5;i++)
printf("%d ",a[i]);
return 0;
假设第一个元素最小 暂存索引,分别和后边的每一个元素比较;比较过程中如果遇到更小的值,索引进行存储;一轮比较完后,再和最左边元素的值进行交换
注意事项
- 稳定性:选择排序是不稳定的排序算法,因为相等的元素可能会改变它们的相对顺序。
- 优化:尽管选择排序的基本形式已经很简洁,但由于其O(n^2)的时间复杂度,它不适合用于大数据集。
- 辅助空间:选择排序是原地排序,除了输入数组外不需要额外的存储空间,空间复杂度为O(1)。
- 适应性:选择排序的运行时间并不依赖于数据的初始状态,无论是近乎有序还是完全无序,其时间复杂度都是O(n^2)。
- 实际应用:由于效率较低,选择排序在实际应用中很少被使用,更高效的排序算法如快速排序、归并排序等通常是更好的选择。
选择排序在教学和理解排序算法的概念时非常有用,但在实际编程应用中,通常被更高效的算法所取代。
预留题目详解:
1.输入任意两个数,输出两数之间(包括这两个数)偶数之和。
思路:将输入的两个数a,b中小的数a,依次加1,加到b的值,每次循环判断这个数a是否为偶数,是则累加到sum中
#include <stdio.h>
int main()
{
int a, b, sum = 0; // 定义两个整数变量a和b,以及一个用于存储偶数之和的变量sum
printf("请输入两个整数:"); // 提示用户输入两个整数
scanf("%d %d", &a, &b); // 读取用户输入的两个整数并分别赋值给变量a和b
if (a > b)
{ // 如果a大于b,交换它们的值
int temp = a;
a = b;
b = temp;
}
for (int i = a; i <= b; i++)
{ // 从较小的数a开始遍历到较大的数b
if (i % 2 == 0)
{ // 判断当前数i是否为偶数
sum += i; // 如果是偶数,则累加到sum中
}
}
printf("两数之间(包括这两个数)偶数之和为:%d", sum); // 输出偶数之和的结果
return 0; // 程序正常结束
}
这个程序是一个C语言程序,用于计算两个整数之间(包括这两个整数)的所有偶数的和。
- 程序通过
#include <stdio.h>
引入了标准输入输出库,以便使用printf()和scanf()函数进行输入输出操作。- 定义了一个名为main的函数,它是C程序的入口点。在main函数中,声明了三个整型变量a、b和sum,分别用于存储用户输入的两个整数以及偶数之和的结果。
- 程序通过printf()函数提示用户输入两个整数,并使用scanf()函数读取用户输入的两个整数并分别赋值给变量a和b。
- 程序通过一个if语句判断a是否大于b,如果是,则交换它们的值,确保a始终小于等于b。
- 程序使用一个for循环从较小的数a开始遍历到较大的数b。在每次循环中,通过取模运算符(%)判断当前数i是否为偶数(即i除以2的余数为0)。如果是偶数,则将其累加到sum变量中。
- 程序通过printf()函数输出偶数之和的结果,并在末尾返回0表示程序正常结束。
2.循环输入一个5位数,判断它是不是回文数。当输入0时循环结束。即12321是回文数,个位与万位相同,十位与千位相同。
思路:
- 使用while循环不断接收用户输入的数字。
- 当输入的数字为0时,跳出循环。
- 判断输入的数字是否为5位数,如果不是则提示重新输入。
- 如果是5位数,提取出各个位置上的数字。
- 判断万位和个位、千位和十位是否相等,如果相等则为回文数,否则不是回文数。
- 输出结果。
#include <stdio.h>
int main()
{
int num;
while (1)
{ // 无限循环,直到输入0结束
printf("请输入一个5位数(输入0结束):");
scanf("%d", &num);
if (num == 0)
{
break; // 如果输入0,跳出循环
}
if (num >= 10000 && num <= 99999)
{ // 判断输入是否为5位数
int a = num / 10000; // 万位
int b = (num % 10000) / 1000; // 千位
int c = (num % 1000) / 100; // 百位
int d = (num % 100) / 10; // 十位
int e = num % 10; // 个位
if (a == e && b == d)
{ // 判断万位和个位、千位和十位是否相等
printf("%d是回文数", num);
}
else
{
printf("%d不是回文数", num);
}
}
else
{
printf("输入的不是5位数,请重新输入。");
}
}
return 0;
}
3.一同学上课违纪看视频,罚他表演才艺,现场抽取10名学生现场打分赋值在数组中,为了 公平起见,去掉其中最高分和最低分,求最终平均值。
思路:
- 首先定义一个整型数组
scores
来存储10名学生的分数。- 使用循环结构,通过
scanf
函数逐个读取用户输入的学生分数,并将其存入数组中。- 在读取分数的过程中,同时计算总分、最高分和最低分。
- 在循环结束后,将总分减去最高分和最低分,得到去掉最高分和最低分后的总分。
- 计算剩余8个分数的平均值,注意要将总分转换为浮点数类型以保留小数部分。
- 最后输出平均分,保留两位小数。
#include <stdio.h>
int main()
{
int scores[10]; // 定义一个数组用于存储10名学生的分数
int sum = 0; // 初始化总分变量为0
int max_score = -1; // 初始化最高分变量为-1(假设最低分数不会低于0)
int min_score = 101; // 初始化最低分变量为101(假设最高分数不会超过100)
printf("请输入10名学生的分数:");
for (int i = 0; i < 10; i++) {
scanf("%d", &scores[i]); // 逐个读取学生分数并存入数组
sum += scores[i]; // 累加分数到总分
if (scores[i] > max_score)
{ // 判断当前分数是否大于最高分
max_score = scores[i]; // 更新最高分
}
if (scores[i] < min_score)
{ // 判断当前分数是否小于最低分
min_score = scores[i]; // 更新最低分
}
}
sum = sum - max_score - min_score; // 去掉最高分和最低分后重新计算总分
float average = (float)sum / 8; // 计算剩余8个分数的平均值,注意转换为浮点数以保留小数部分
printf("去掉最高分和最低分后的平均分为:%.2f", average); // 输出平均分,保留两位小数
return 0;
}
本文就写到这了,喜欢的码友可以点赞欧。