1,负数取模的规则是:计算得到的数值和除数和被除数的符号无关,最后结果的符号由被除数的符号进行决定
2,==运算符不可以比较两个字符串是否相等,因为比较的是两者的地址, 就算是常量字符串也不行。
4,realloc进行缩容,缩容过小会造成数据截断,丢失数据。
特殊:realloc(ptr,0)释放原来的内存,返回NULL.不建议这样使用,释放内存还是使用free和delete
3,
输出的结果为123456,%5表示最少输出5个字符。不足5位通过空格进行补充。超过5位就正常输出。
4,如果print()有n个占位符, 就有n+1个参数

n个占位符对应n个参数,加上字符串就是n+1个参数。
5,scanf中的占位符%s表示读取一个字符串,遇到空白就停止

6,scanf()处理数值占位符时,会自动跳过空白字符,包括空格,制表符,换行符。
处理字符占位符时,不会忽略空白字符(空格,换行符,制表符)
| 占位符类型 | 是否跳过空白字符 | 说明 |
|---|---|---|
数值型 :%d %f %lf %x 等 |
✅ 自动跳过 | 忽略输入前的空格、制表符、换行符 |
字符串 :%s |
✅ 自动跳过 | 忽略前导空白,读到空白字符停止 |
字符 :%c |
❌ 不跳过 | 读取当前第一个字符,包括空格和换行符 |

%d无论中间有多少个空格都会跳过,应为他读取的是数字
%c表示读取字符,空白字符也是字符,所以会读取
输入的A前面是一个/n,a1读取了"/n",a2读取了"A".
打印时先打印一个换行符,再打印字符"A"
补充1:

此处可见没有省略空白字符
导致c2为空格
7,变长数组(VLA)
C99之前没有变长数组,在定义和初始化时数组\[\]中的数必须是常数,但是在C99之后引了变长数组后,只要变量提前已经赋一个常数值,就可以在\[\]填入一个变量。特殊的:C++不支持变长数组。
MSVC编译器:微软的MSVC编译器至今没有完整支持C99标准中的变长数组(VLA)它主要支持的是C++标准,C++标准本身不支持变长数组。
变长数组(VLA)的注意事项:
_1,VLA不能进行初始化
int n =10;
int arrn = {0}; (X)
原因:数组在编译时就要进行初始化,但是此时变量n不存在。变量n在运行时才存在。
_2,VLA不能时全局变量和静态变量
原因:全局变量和静态变量在程序启动前,内存就分配完成了,大小是一个编译期常量。而VLA是运行时变量
_3,当变量n过大时,arrn可能导致栈溢出
int n =1000000;
int arrn; //栈溢出风险
_4,变长数组的大小一旦确定就无法进行改变。
8,

sizeof(acX)> sizeof(acY):acX中的字符比acY中的字符多一个"\0",所以更大
strlen(acX)和strlen(acY)无法进行比较,因为strlen记录的时"\0"前的字符个数。
acY中没有"\0",所以strlen(acY)是一个随机值。
9,函数的实参不止可以是变量,也可以是常数,表达式,函数返回值,数组元素,结构体成员,宏定义等等。
10,左对齐和右对齐
右对齐:
例:%2d 右对齐,不足的补充空格 ,超过2位原样输出
%2f同理,右对齐,不足两位,用空格补充。
%.2d 和 %02d,右对齐,不足的补充0,超过2位原样输出
%.2f,精度控制为2位,小数点后保留两位。
左对齐:
%-2d 左对齐,不足的用空格进行补充,超过2位原样输出
11,数组的逆置

cpp
void reserve(int arr[],int size)
{
int left = 0;
int right = size - 1;
while (left++ < right--)
{
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
}
}
12,判断素数
cpp
#include <stdbool.h>
#include <math.h>
//实现判断素数的函数
bool is_prime(int k)
{
//处理特殊情况--负数,0,1都不是素数
if (k <= 1)
{
return false;
}
int n = sqrt(k); //防止每次都计算sqrt(k)
for (int i = 2;i <= n;i++)
{
if (k % i == 0)
{
return false;
}
}
return true;
}
13,轮转数组

解法一:再创建一个数组,回头拷贝
cpp
void rotate(int* nums, int numsSize, int k)
{
//使用额外的数组,最后拷贝回去
int arr1[numsSize];
for(int i = 0;i<numsSize;i++)
{
//(k+i)%numsSize
//这个式子不仅考虑超出时循环的情况
//还考虑了不同的初始位置的影响
arr1[(k+i) % numsSize] = nums[i];
}
//拷贝回去
for(int i = 0;i<numsSize;i++)
{
nums[i] = arr1[i];
}
}
时间复杂度和空间复杂度都为O(n)
解法二:翻转数组
原理:

cpp
//交换两个元素值
void Swap(int* a,int* b)
{
int t = *a;
*a = *b;
*b = t;
}
//翻转数组
void reserve(int num[],int start,int end)
{
while(start<end)//不能在这里直接对start和end++--,因为后面还要使用
{
Swap(&num[start],&num[end]);
start++;
end--;
}
}
void rotate(int* nums, int numsSize, int k)
{
//解决循环
k %= numsSize;
//翻转数组写法
reserve(nums,0,numsSize-1);
reserve(nums,0,k-1);
reserve(nums,k,numsSize-1);
}
14,打印水仙花数

//打印0~100000之间的水仙花数
//常见问题--计算之后丢失原来的值,要进行提前赋值保存
int main()
{
for (int i = 0;i <= 100000;i++)
{
int c = i;
int tmp = c;
if (c == 0)
{
printf("0 ");
continue;
}
//记录位数
int a = 0;
while (c > 0)
{
c = c / 10;
a++;
}
//计算之后c丢失原始值
int count = 0;
int j = a;
while (j--)
{
//得到每一位--每次求最后一位
int n = tmp % 10;
tmp /= 10;
count += pow(n, a);
}
if (count == i)
{
printf("%d ", count);
}
}
return 0;
}
15,不创建额外变量,实现两个数的交换
//交换两个变量
//方法一--使用异或操作符
void Judgement1(int* a, int* b)
{
//a ^ 0 == a a ^ a == 0
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
//加减交换法
void Judgement2(int* a, int* b)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
int main()
{
int a = 3;
int b = 5;
printf("%d %d\n", a, b);
Judgement2(&a, &b);
printf("%d %d", a, b);
}