目 录CONTENT

文章目录
C

C语言基础2

~梓
2025-05-21 / 0 评论 / 0 点赞 / 12 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

一、取地址运算符

1. 基本作用:获取变量的内存地址

  • 语法&变量名
  • 返回值:变量在内存中的起始地址(类型为对应指针类型)。
int x = 10;
int* ptr = &x;  // ptr 存储 x 的内存地址

这里,&x 返回一个 int* 类型的值(指向 int 的指针),并赋值给指针变量 ptr

2. 与指针的关系

  • 指针变量:存储内存地址的变量,声明时需指定指向的数据类型。
  • 解引用操作符 \*:与 & 互为逆运算,通过地址访问对应内存中的值。
int x = 10;
int* ptr = &x;  // ptr 指向 x 的地址

printf("%p\n", ptr);    // 输出 x 的地址(如 0x7ffe5360f9c4)
printf("%d\n", *ptr);   // 通过指针解引用,输出 10(即 x 的值)

3. 示例:交换两个数的值(函数实现):

void swap(int* a, int* b) {
    int temp = *a;  // 读取 a 地址处的值
    *a = *b;        // 将 b 地址处的值写入 a 地址
    *b = temp;      // 将 temp 的值写入 b 地址
}

int main() {
    int x = 10, y = 20;
    swap(&x, &y);   // 传递 x 和 y 的地址
    printf("%d, %d\n", x, y);  // 输出 20, 10
}
  • &x&y 将变量地址传递给函数。
  • 函数内部通过 *a*b 直接操作原始内存,实现值的交换。

4. 与数组的关系

数组名在大多数表达式中会隐式转换为指向首元素的指针:

int arr[3] = {1, 2, 3};
int* ptr = arr;  // 等价于 int* ptr = &arr[0];

printf("%d\n", *ptr);      // 输出 1(首元素的值)
printf("%d\n", *(ptr+1));  // 输出 2(第二个元素的值)

5. 反面教材

混淆 &\*

int x = 10;
int* ptr = &x;  // 正确:ptr 存储 x 的地址
int* ptr2 = x;  // 错误:无法将 int 赋值给 int*

未正确传递地址

void increment(int* num) {
    (*num)++;  // 解引用后递增
}

int main() {
    int x = 5;
    increment(x);   // 错误:期望 int*,传入 int
    increment(&x);  // 正确:传递地址
    return 0;
}

二、scanf

scanf 是标准库提供的输入函数,用于从标准输入(通常是键盘)读取格式化数据。

一、基本语法

#include <stdio.h>

int scanf(const char *format, ...);
  • 参数:
    • format:格式化字符串,指定输入的格式(如 %d 表示整数,%f 表示浮点数)。
    • 可变参数:接收输入值的变量地址(使用 & 运算符获取)。
  • 返回值:成功匹配并赋值的输入项数量,遇错误或文件结束符(EOF)时返回 EOF

二、常见格式说明符

格式符 说明 示例输入
%d 读取十进制整数 123
%f 读取浮点数(float) 3.14
%lf 读取双精度浮点数 3.14159
%c 读取单个字符 a
%s 读取字符串(遇空格停止) hello
%[^\n] 读取整行字符串(包括空格) hello world

三、示例用法

1. 读取整数
int num;
printf("请输入一个整数: ");
scanf("%d", &num);  // 输入 123 → num = 123
2. 读取多个值
int a, b;
printf("请输入两个整数: ");
scanf("%d %d", &a, &b);  // 输入 1 2 → a=1, b=2
3. 读取浮点数
变量类型 scanf 格式说明符 示例
float %f scanf("%f", &num);
double %lf scanf("%lf", &num);
float f;
scanf("%f", &f);  // 输入 3.14 → f=3.14
4. 读取字符串
char name[20];
scanf("%s", name);  // 输入 hello → name="hello"
// 注意:scanf 遇空格停止,输入 "hello world" 时,name="hello"
5. 读取带空格的字符串
char sentence[100];
scanf("%[^\n]", sentence);  // 输入 hello world → sentence="hello world"
6.读取单个字符
#include <stdio.h>

int main() {
    char ch;
    printf("请输入一个字符: ");
    scanf("%c", &ch);  // 读取一个字符
    printf("你输入的字符是: %c\n", ch);
    return 0;
}

需留意缓冲区问题

四、注意事项

1. 地址传递
  • 除数组名(本身是地址)外,其他变量必须用 & 获取地址:
int num;
scanf("%d", &num);  // 正确
scanf("%d", num);   // 错误!未传递地址
2. 输入缓冲区问题
  • scanf 读取后可能残留换行符 \n,影响后续输入:
char name[20];
int age;
scanf("%d", &age);     // 输入 20 后残留 \n
scanf("%s", name);     // \n 被读取,name 为空!

解决方案

// 方法1:在格式字符串中加空格,消耗换行符
scanf(" %s", name);    // 空格消耗 \n

// 方法2:手动清除缓冲区
while (getchar() != '\n');  // 消耗所有剩余字符
3. 字符串输入限制
  • %s 遇空格停止,且不检查数组边界,可能导致缓冲区溢出:
char name[5];
scanf("%s", name);  // 输入超过4个字符时会溢出!

安全写法:用 %ns 限制输入长度(n 为最大字符数):

scanf("%4s", name);  // 最多读取4个字符,自动留空间给 '\0'

五、高级用法

1. 正则表达式匹配
  • 使用 [] 自定义字符集
char str[20];
scanf("%[0-9]", str);  // 只读取数字字符,输入 1a2 → str="1"
2. 忽略输入
  • 使用 * 丢弃匹配的输入:
int a, b;
scanf("%d %*d %d", &a, &b);  // 输入 1 2 3 → a=1, b=3(2被忽略)

六、与其他输入函数的对比

函数 特点 适用场景
scanf 格式化输入,支持多种类型 结构化数据输入
fgets 读取整行,安全(指定缓冲区大小) 读取含空格的字符串
getchar 读取单个字符 字符处理、菜单选择

三、C 语言和 Python 在处理字符与整数相加机制

1. C 语言:字符本质是整数

在 C 中,字符型(char)本质上就是 1 字节的整数,存储的是字符的 ASCII 码值。因此,字符与整数的加减运算是直接对 ASCII 码进行数值运算

#include <stdio.h>

int main() {
    char c = 'A';      // ASCII码为65
    int num = c + 1;   // 65 + 1 = 66
    printf("%d\n", num);  // 输出:66
    printf("%c\n", num);  // 输出:B(ASCII码66对应的字符)
    return 0;
}

关键点

  • 字符 'A'直接参与加法运算时,会被隐式转换为整数 65。
  • 运算结果(整数)可以通过 %c格式说明符转换回字符输出。

2. Python:字符串不可变,需显式转换

在 Python 中,字符用长度为 1 的字符串表示,字符串是不可变对象,不能直接与整数相加。若要实现类似 C 语言的字符运算,需通过 ord()chr()函数进行显式转换:

  • ord(c):将字符转换为 ASCII 码值(整数)。
  • chr(n):将整数转换为对应的 Unicode 字符。
c = 'A'
num = ord(c) + 1   # ord('A') 返回65,65 + 1 = 66
print(num)         # 输出:66
print(chr(num))    # 输出:B(ASCII码66对应的字符)

错误示例

直接将字符串与整数相加会报错:

c = 'A'
print(c + 1)  # 报错:TypeError: can only concatenate str (not "int") to str

3. 为什么会有这种差异?

  • C 语言是静态类型语言,设计之初就允许对字符进行数值运算,这与底层硬件表示(ASCII 码)直接对应。
  • Python是动态类型语言,字符串是高级抽象数据类型,需要通过函数显式转换,以保持类型安全。

4.总结

特性 C 语言 Python
字符本质 1 字节整数(ASCII 码) 长度为 1 的字符串对象
加法运算 直接对 ASCII 码进行数值运算 不允许字符串与整数相加,需显式转换
示例 'A' + 1 → 66(整数) 'A' + 1 → 报错
转换函数 隐式转换,%c格式说明符 ord()chr()
0
C

评论区