main.c 源文件
#include <stdio.h>
/**
* C语言中#开头的称为预处理指令
例如:#include #define #if
* C语言中没有导包的说法
如果一个函数在多个.c文件中重复使用,那么函数要声明在.h头文件中,
如果仅在当前文件中使用,可以直接定义该函数。
* 文件的类型
xxx.h 头文件, 用于包含函数声明、宏定义、结构体和类的定义等
xxx.c 实现文件(源文件)
* 导入的两种形式
#include <filename>:
这种形式仅在系统头文件目录中搜索头文件。
一般用于包含标准库头文件。
#include "filename":
这种形式首先在当前目录或源文件所在目录搜索头文件。
如果在当前目录中找不到指定的头文件,再会在系统头文件目录中搜索。
*/
#include <stdlib.h>
#include <string.h>
// 自定义头文件,声明函数 funcMethod99
#include "HeaderDemo.h"
// 宏常量
#define LEN 10
// 宏函数
#define SQUARE(x) ((x) * (x))
// 定义一个多行宏函数,计算并打印两个数的和
#define PRINT_SUM(a, b) do { \
int sum = (a) + (b); \
printf("Sum of %d and %d is %d\n", a, b, sum); \
} while(0)
// int aa = 20; // 报错: multiple definition of `aa'
// 从demo2.c文件引入变量aa, 一个全局变量只能有一处定义
extern int aa;
// 声明函数 void 无返回值
void dataType() {
// 字符和字符串
// char字符 (1个字节)
char c = 'A';
// cahr数组 (字符长度 + 一个结束符 '\0', 一共占12 个字符 + 1 个结束符, 13个字节)
char str[] = "Hello, World!";
size_t length = strlen(str);
printf("字符: %c\n", c);
printf("字符串: %s\n", str);
printf("字符串长度: %zu\n", length);
// 整数 shor(短整型 2字节)
// int(整形 4字节)
// long(长整型通常 4个字节,在某些64位的UNIX系统 8个字节,不常用)
// long long(长长整型 8个字节)
int i = 123;
unsigned int u = 123;
printf("有符号整数: %d\n", i);
printf("无符号整数: %u\n", u);
printf("八进制: %o\n", i);
printf("十六进制: %x\n", i);
// 浮点数
float f = 123.456f;
double d = 123.456789;
printf("浮点数: %f\n", f);
printf("双精度浮点数: %lf\n", d); // %lf double标识符
printf("科学计数法: %e\n", d);
// 格式控制
printf("宽度控制: %15f\n", f); // %15f 宽度为15,不足位数 在前面 空格填充
printf("精度控制: %.2f\n", f); // %.2f 保留两位小数
printf("零填充: %010d\n", i); // 宽度10,不足位数 在前面 零填充
printf("左对齐: %-10d\n", i); // 宽度10,不足位数 在后面 空格填充
// 指针 得到的是一个十六进制表示的内存地址,它表示变量 i 在内存中的位置
// &i 前面是 与符号 在这里看着有点抽象
printf("指针: %p\n", (void *) &i); // 000000000061FDC4
// 百分号
printf("百分号: %%\n");
}
void strFormat() {
char name[] = "Alice";
int age = 30;
float weight = 65.50f;
// 使用格式化字符串输出变量的值
printf("Name = %s, Age = %d, Weight = %.1f\n", name, age, weight);
// 自动类型转换
float f = 10;
printf("%.0f\n", f);
}
int batchStatement() {
int a, b = 50, c = 100;
// 在 C 语言中,局部变量如果没有被显式初始化,它们的值是未定义的,即它们可能包含任意值。
printf("%d\n", a); // 6644585
printf("%d\n", b);
printf("%d\n", c);
return 0;
}
int calculate() {
// 算术运算符 加+、减-、乘*、除/、取余%
int a = 5, b = 3;
float c = a / b; // 在运算过程中是将两个整数计算,先得到结果整数1,再赋值float,所以是1.00
printf("%.2f\n", c); // 1.00
float d = 5, e = 3;
float f = d / e;
printf("%.2f\n", f); // 1.67
int j = 100;
int h = 3;
double k = j * 1.0 / h;
printf("%.3f\n", k);
// i++ 和 ++i
int i = 1;
// int u = ++ i; // 先+1 后赋值 结果2
int u = i++; // 先赋值 后+1 结果1
printf("%d\n", u);
return 0;
}
void sizeofMethods() {
// 基本数据类型的大小
printf("Size of int: %zu bytes\n", sizeof(int));
printf("Size of float: %zu bytes\n", sizeof(float));
printf("Size of double: %zu bytes\n", sizeof(double));
printf("Size of char: %zu bytes\n", sizeof(char));
// 变量的大小
int a = 10;
float b = 20.5f;
double c = 30.5;
char d = 'A';
printf("Size of variable a: %zu bytes\n", sizeof(a));
printf("Size of variable b: %zu bytes\n", sizeof(b));
printf("Size of variable c: %zu bytes\n", sizeof(c));
printf("Size of variable d: %zu bytes\n", sizeof(d));
// 数组的大小
int numbers[5] = {1, 2, 3, 4, 5};
printf("Size of array: %zu bytes\n", sizeof(numbers));
printf("Size of one element: %zu bytes\n", sizeof(numbers[0]));
// 数组长度
printf("Number of elements in the array: %zu\n", sizeof(numbers) / sizeof(numbers[0]));
// 如果sizeof的参数是一个数据类型名称,那么必须使用括号
// 如果sizeof的参数是一个变量名或表达式,那么括号是可选的
printf("Size of int: %zu bytes\n", sizeof(int));
printf("Size of variable a: %zu bytes\n", sizeof a);
}
void swap(int *a, int *b) {
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
void array() {
// 字符数组
char str[] = "Hello, world";
printf("charArr[0]: %c\n", str[0]);
// 固定长度int数组
int numberArr[5] = {1, 2, 3, 4, 5};
int numberArrLength = sizeof numberArr / sizeof numberArr[0];
printf("length: %d\n", numberArrLength);
for (int i = 0; i < numberArrLength; ++i) {
printf("numberArr: %d\n", numberArr[i]);
}
// 指针数组(不指定长度)
char *strArr[] = {"腾讯", "微信", "QQ", "小马哥"};
int strArrLength = sizeof strArr / sizeof strArr[0];
for (int i = 0; i < strArrLength; ++i) {
printf("strArr: %s\n", strArr[i]);
}
// int数组的倒序输出
int arr[] = {100, 200, 300, 400, 500};
int arrLength = sizeof arr / sizeof(int);
for (int i = (arrLength - 1); i >= 0; --i) {
printf("reverseArr: Index: %d number: %d\n", i, arr[i]);
}
// 异或 对数组进行 交换倒序
for (int i = 0; i < arrLength / 2; ++i) {
swap(&arr[i], &arr[arrLength - i - 1]);
}
for (int i = 0; i < arrLength; ++i) {
printf("Reversed ^ array: %d\n", arr[i]);
}
}
void strMethods() {
char str[] = "Hello, World!";
size_t length = strlen(str); // length 为 13
printf("strlen:计算字符串的长度(不包括终止的空字符 \\0): %zu\n", length);
char dest[20];
strcpy(dest, str);
printf("strcpy:复制字符串: %s\n", dest);
char dest2[20];
strncpy(dest2, str, 3); // 只复制前 3 个字符
dest2[3] = '\0'; // 手动添加字符串终止符
printf("strncpy:复制指定长度的字符串: %s\n", dest2);
char str1[20] = "Hello,"; // 指定长度需要保证,后面拼接进来的字符串有足够的空间使用,可以为空 str1[]
char str2[] = "World!";
strcat(str1, str2); // 将 str2 连接到 str1 后面
printf("strcat:字符串拼接: %s\n", str1);
char str3[20] = "Hello, ";