文章目录
- C语言常见问题
-
- [1. 判断是否为质数](#1. 判断是否为质数)
- [2. 格式控制](#2. 格式控制)
-
- [printf("%0*d\n", k, ans[k_]);](#printf("%0*d\n", k, ans[k_]);)
- [3. 读取字符串](#3. 读取字符串)
- [4. 通讯录录入](#4. 通讯录录入)
- [5. 存储大数(long)](#5. 存储大数(long))
- [6. int,long long,double,float等的范围(和精度)](#6. int,long long,double,float等的范围(和精度))
- [6. C语言pi使用](#6. C语言pi使用)
- [7. 布尔值](#7. 布尔值)
- [8. 求两个浮点数相除的余数](#8. 求两个浮点数相除的余数)
-
- [示例 1:计算余数](#示例 1:计算余数)
- [示例 2:检查一个数是否为整数](#示例 2:检查一个数是否为整数)
- 注意事项
- [8. getchar用法](#8. getchar用法)
- [9. 获取数组长度](#9. 获取数组长度)
- [10. 获取字符串长度](#10. 获取字符串长度)
- [11. ASCLL](#11. ASCLL)
- [12. 向上取整算法](#12. 向上取整算法)
- [13. c++中有没有一种数据结构,既能像列表一样进行查找,又能像结构体那样能存放不同类型的数据](#13. c++中有没有一种数据结构,既能像列表一样进行查找,又能像结构体那样能存放不同类型的数据)
C语言常见问题
1. 判断是否为质数
c
int ip(int n) {
if(n==1||n==0)return 0;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)return 0;
}
return 1;
}
2. 格式控制
printf("%0*d\n", k, ans[k_]);
- %0*d 是 printf 函数中的格式说明符。
- %d 表示输出一个十进制整数。
- 0 表示如果整数的长度小于 k,则在前面补零,使整数总宽度达到 k 位。
- *表示 k 是一个变量的值,而不是一个固定的数字。
3. 读取字符串
使用for循环读取字符串(跳不过空格)
c
#include <stdio.h>
int main() {
char str[] = "Hello, World!";
for (int i = 0; str[i] != ''; i++) {
printf("Character at index %d is %cn", i, str[i]);
}
return 0;
}
用while循环+getchar()(可以跳过空格)
c
#include <stdio.h>
int main() {
char buffer[100];
int i = 0;
char ch;
printf("请输入一行字符串:");
while ((ch = getchar()) != 'n' && ch != EOF && i < 99) {
buffer[i++] = ch;
}
buffer[i] = ''; // 添加终止符
printf("读取的字符串是:%s\n", buffer);
return 0;
}
用do-while+getchar()遇到回车结束!
cpp
#include<bits/stdc++.h>
using namespace std;
vector<int> a;
int main(void)
{
int i=0;
do{
int num;cin>>num;a.push_back(num);i++;
}while(getchar()!='\n');
for(int i=0;i<a.size();i++)printf("%d ",a[i]);
return 0;
}
4. 通讯录录入
c
#include<stdio.h>
typedef struct contacts {
char name[11];
char birthday[11];
char sex;
char fixedPhoneNumber[17];
char mobilePhoneNumber[17];
} Contacts;
int main(void) {
int N;
scanf("%d", &N);
// 联系人信息录入
Contacts contacts[10];
for (int i = 0; i < N; i++) {
scanf("%s %s %c %s %s", contacts[i].name, contacts[i].birthday, &contacts[i].sex, contacts[i].fixedPhoneNumber, contacts[i].mobilePhoneNumber);
}
int K;
scanf("%d", &K);
// 采集用户想要查询的编号
int choices[10];
for (int i = 0; i < K; i++) {
scanf("%d", &choices[i]);
}
// 按题目要求格式输出联系人信息
for (int i = 0; i < K; i++) {
if (choices[i] >= N || choices[i] < 0) {
printf("Not Found\n");
} else {
printf("%s %s %s %c %s\n", contacts[choices[i]].name, contacts[choices[i]].fixedPhoneNumber, contacts[choices[i]].mobilePhoneNumber, contacts[choices[i]].sex, contacts[choices[i]].birthday);
}
}
return 0;
}
typedef struct contacts
这一行是 C 语言中的一个语法,用于定义一个新的类型名 Contacts
,这个类型名指向一个结构体 struct contacts
。
这里解释一下这行代码的含义:
typedef
是 C 语言中的一个关键字,用于定义一个新的类型名。
struct
是 C 语言中的一个关键字,用于声明一个结构体。
contacts
是您定义的新类型名,它将指向 struct contacts 结构体。
struct contacts
是结构体的定义,它包含以下字段:
name
:一个字符数组,用于存储联系人的名字,长度为 11。
birthday
:一个字符数组,用于存储联系人的生日,长度为 11。
sex
:一个字符变量,用于存储联系人的性别。
fixedPhoneNumber
:一个字符数组,用于存储联系人的固定电话号码,长度为 17。
mobilePhoneNumber
:一个字符数组,用于存储联系人的移动电话号码,长度为 17。
通过使用 typedef struct contacts
,可以在代码中使用 Contacts
类型名来代替 struct contacts
,这样可以使代码更加清晰和易于阅读。
例如,在 main 函数中,定义了一个 Contacts 类型的数组 contacts,并在循环中使用 scanf 函数来读取并存储联系人的信息。
c
Contacts contacts[10];
for (int i = 0; i < N; i++) {
scanf("%s %s %c %s %s", contacts[i].name, contacts[i].birthday, &contacts[i].sex, contacts[i].fixedPhoneNumber, contacts[i].mobilePhoneNumber);
}
在这里,contacts[i].name
表示 i 索引的联系人 name
字段的地址,而 &contacts[i].sex
表示 i 索引的联系人 sex
字段的地址。
5. 存储大数(long)
使用long类型
long类型用于存储较大的整数,但它的范围仍然有限(通常是32位或64位,取决于系统和编译器)。以下是如何使用long:
c
#include <stdio.h>
int main() {
long num = 2147483647; // 示例数值,接近long的最大值
printf("The number is: %ld\n", num);
return 0;
}
注意:
使用%ld格式化输出long类型的变量。
long的最大值可以用LONG_MAX(在limits.h中定义)来获取。
6. int,long long,double,float等的范围(和精度)
名称 全称类型说明符 缩写类型说明符 位数 范围
整型 int int 16位 -32768至+32767
无符号整型 unsigned int unsigned 16位 0 至 65,535
短整型 short int short 16位 -32768至+32767
无符号短整型 unsigned short int unsigned short 16位 0 至 65,535
长整型 long int long 32位 -2,147,483,648 至 2,147,483,647( -2^63 ~ 2^63-1)
无符号长整型 unsigned long int unsigned long 32位 0至4,294,967,295
6. C语言pi使用
使用数学库中的M_PI常量
C语言的标准数学库<math.h>提供了一个常量M_PI,它表示π的值。使用M_PI常量是最简单和最常见的方法之一。
c
#include <stdio.h>
#include <math.h>
int main() {
printf("The value of PI is: %fn", M_PI);
return 0;
}
7. 布尔值
在C99标准之后,C语言引入了<stdbool.h>头文件,它定义了bool、true和false。使用这个头文件,你可以更明确地定义和使用布尔变量:
c
#include <stdio.h>
#include <stdbool.h>
int main() {
bool isTrue = true; // 真值
bool isFalse = false; // 假值
// 使用if语句检查布尔变量
if (isTrue) {
printf("This is true.\n");
} else {
printf("This is false.\n");
}
if (isFalse) {
printf("This is true.\n");
} else {
printf("This is false.\n");
}
return 0;
}
在这个例子中,bool实际上是一个_Bool类型的别名,它由<stdbool.h>头文件定义。true和false分别被定义为1和0。使用<stdbool.h>可以使代码更加清晰和易于理解。
8. 求两个浮点数相除的余数
使用数学函数 fmod
fmod 函数是 C 标准库 <math.h> 中的一部分,它可以用来计算两个浮点数的余数。
fmod
函数是 C 标准库 <math.h>
中的一部分,它用来计算两个浮点数相除的余数。其原型如下:
c
double fmod(double x, double y);
这个函数返回 x
除以 y
的余数,并且这个余数的符号与 x
的符号相同。如果 y
是零,那么 fmod
函数的行为是未定义的。
下面是 fmod
函数的一些使用示例:
示例 1:计算余数
c
#include <stdio.h>
#include <math.h>
int main() {
double x = 10.0;
double y = 3.0;
double result = fmod(x, y);
printf("The remainder of %f divided by %f is %f\n", x, y, result);
return 0;
}
在这个例子中,fmod(10.0, 3.0)
将返回 1.0
,因为 10.0
除以 3.0
的余数是 1.0
。
示例 2:检查一个数是否为整数
c
#include <stdio.h>
#include <math.h>
int isInteger(double num) {
return fmod(num, 1) == 0;
}
int main() {
double num1 = 5.0;
double num2 = 5.5;
if (isInteger(num1)) {
printf("%f is an integer.\n", num1);
} else {
printf("%f is not an integer.\n", num1);
}
if (isInteger(num2)) {
printf("%f is an integer.\n", num2);
} else {
printf("%f is not an integer.\n", num2);
}
return 0;
}
在这个例子中,我们使用 fmod
函数来检查一个数是否能被 1
整除,以此来判断它是否为整数。
注意事项
- 使用
fmod
函数之前,需要包含<math.h>
头文件。 fmod
函数的返回值类型是double
,但是也有float
和long double
版本,分别是fmodf
和fmodl
。- 当
y
是零时,fmod
的行为是未定义的,可能会导致运行时错误。 - 由于浮点数的精度问题,使用
fmod
来检查一个数是否为整数时,可能会有意外的结果。通常,这种方法在数值足够小且没有精度损失的情况下是可行的。
8. getchar用法
getchar()
是 C 语言标准库函数之一,它用于从标准输入(通常是键盘)读取下一个字符。getchar()
函数的原型定义在 <stdio.h>
头文件中。
下面是 getchar()
的一些基本用法:
读取单个字符
c
#include <stdio.h>
int main() {
int c; // getchar 返回的是 int 类型,以容纳 EOF(-1)
c = getchar(); // 读取下一个字符,包括空格、制表符、换行符等
if (c != EOF) { // EOF 是文件结束标志
putchar(c); // 打印读取的字符
}
return 0;
}
在上面的例子中,getchar()
读取一个字符,然后 putchar()
将该字符打印到标准输出。
跳过换行符
当你使用 scanf()
读取字符串或字符后,通常换行符会留在输入缓冲区中。你可以使用 getchar()
来读取并丢弃这个换行符。
c
#include <stdio.h>
int main() {
char ch;
printf("Enter a character: ");
scanf("%c", &ch); // 读取一个字符
getchar(); // 读取并丢弃换行符
// ... 其他代码 ...
return 0;
}
读取直到文件结束
你可以使用 getchar()
在循环中读取字符,直到遇到文件结束符(EOF)。
c
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF) { // 循环直到 EOF
putchar(c); // 打印字符
}
return 0;
}
在这个例子中,程序会一直读取字符并打印,直到用户输入文件结束符(通常是 Ctrl+D 在 Unix/Linux 系统上,或者 Ctrl+Z 在 Windows 系统上)。
注意事项
getchar()
的返回值是int
类型,因为它需要能够返回EOF
(通常是-1
),而-1
超出了char
类型的范围。getchar()
在读取到文件结束符(EOF)时返回EOF
。- 如果输入缓冲区中没有字符,
getchar()
会阻塞,直到有输入可用。
使用getchar()
时,需要确保输入缓冲区中确实有字符可读,否则程序可能会挂起等待用户输入。
9. 获取数组长度
在C语言中,数组本身并不直接存储其长度信息,因为数组在传递给函数时会退化为指针,指针不包含关于数组大小的信息。不过,你可以通过以下几种方法来获取数组的长度:
-
在声明数组时计算长度 :
当你在同一作用域内声明数组时,你可以通过计算数组的总大小除以单个元素的大小来得到数组长度。cint array[] = {1, 2, 3, 4, 5}; size_t length = sizeof(array) / sizeof(array[0]);
-
将数组长度作为参数传递给函数 :
当你需要将数组传递给函数时,必须手动传递数组的长度,因为函数本身无法知道。cvoid printArray(int arr[], size_t len) { for (size_t i = 0; i < len; ++i) { printf("%d ", arr[i]); } printf("\n"); } int main() { int array[] = {1, 2, 3, 4, 5}; size_t length = sizeof(array) / sizeof(array[0]); printArray(array, length); return 0; }
-
使用宏定义来计算长度 :
在某些情况下,可以使用宏来创建一个通用函数,该函数可以计算任何数组的长度。c#define ARRAY_LENGTH(array) (sizeof(array) / sizeof((array)[0])) int main() { int array[] = {1, 2, 3, 4, 5}; size_t length = ARRAY_LENGTH(array); // 使用length... return 0; }
请注意,以上方法仅适用于在数组声明的作用域内或传递数组长度信息时。如果你有一个指向数组的指针,那么就没有直接的方式来获取数组的长度,除非你事先知道长度并传递它。在C语言中,维护数组长度信息是程序员的责任。
10. 获取字符串长度
在C语言中,获取字符串长度的常用方法是使用标准库函数 strlen
,该函数定义在头文件 <string.h>
中。下面是如何使用 strlen
函数来获取字符串长度的示例:
c
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
size_t length = strlen(str); // 使用strlen函数获取字符串长度
printf("The length of the string is: %zu\n", length);
return 0;
}
在上面的代码中,strlen
函数返回字符串 str
的长度,不包括终止的空字符 ('\0'
)。返回值类型是 size_t
,它是一个无符号整数类型,通常用于表示大小和计数。
请记住,strlen
函数只适用于以空字符结尾的字符串(C字符串)。如果你有一个字符数组,但不是以空字符结尾的,使用 strlen
可能会导致未定义行为。
11. ASCLL
12. 向上取整算法
m/n向上取整方法:
cpp
(m - 1) / n + 1
13. c++中有没有一种数据结构,既能像列表一样进行查找,又能像结构体那样能存放不同类型的数据
在 C++ 中,可以使用 std::tuple
或 std::pair
来创建一个可以存放不同类型数据的结构。这两个模板类可以被视为轻量级的结构体,能够存储不同类型的元素。下面是关于这两个数据结构的一些信息:
std::pair
:
std::pair
是一个模板类,可以存储两个不同类型的数据。当你需要存储两个元素时,它非常有用。
cpp
#include <utility> // 包含 pair 的定义
std::pair<int, std::string> p(1, "example");
std::tuple
:
std::tuple
是一个模板类,可以存储任意数量的不同类型的数据。当你需要存储超过两个不同类型的元素时,std::tuple
更合适。
cpp
#include <tuple> // 包含 tuple 的定义
std::tuple<int, double, std::string> t(1, 2.3, "example");
为了在列表中进行查找,你可以使用 std::vector
或 std::list
等容器来存储这些 pair
或 tuple
的实例,并使用标准库中的算法(如 std::find_if
)来查找特定的元素。
以下是一个示例,展示了如何使用 std::vector
和 std::tuple
来存储不同类型的数据,并查找特定元素:
cpp
#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm> // 用于 std::find_if
int main() {
// 创建一个存储 tuple 的 vector
std::vector<std::tuple<int, double, std::string>> vec;
// 向 vector 添加 tuple 元素
vec.emplace_back(1, 2.3, "Alice");
vec.emplace_back(2, 3.4, "Bob");
vec.emplace_back(3, 4.5, "Charlie");
// 查找名字为 "Bob" 的 tuple
auto it = std::find_if(vec.begin(), vec.end(), [](const auto& item) {
return std::get<2>(item) == "Bob";
});
if (it != vec.end()) {
// 找到了匹配的 tuple
std::cout << "Found: " << std::get<0>(*it) << ", " << std::get<1>(*it) << ", " << std::get<2>(*it) << std::endl;
} else {
std::cout << "Not found." << std::endl;
}
return 0;
}
在这个例子中,我们创建了一个 vector
来存储 tuple
,每个 tuple
包含一个 int
、一个 double
和一个 string
。然后,我们使用 std::find_if
算法和一个 lambda 表达式来查找具有特定名字的 tuple
。如果找到了匹配的元素,我们就打印出来。