1. 指针±整数还是一个指针,至于具体这个指针指向哪边去了,就根据三个东西。1. 正负号。正号就是往高地址方向走,负号就是低地址的方向走。2. 指针变量类型决定了步长。3. 数字决定了步数
2. 逆序字符串的话一般的方法就是头尾成一对,然后交换位置,然后向中间靠拢。
3. 赋值运算符的优先级是非常低的
4. 如果函数内的局部变量和全变量同名,那么在函数内部局部变量会屏蔽全局变量,里面吭哧吭哧都是在对局部变量进行操作。事实上,同名不同名根本就没关系,如果你深入到内存层面去理解,深入到汇编代码去理解,说白了,其实编译器才不认识你的名字呢,并且就算函数内外同名,内部的一切操作也改变不了外面与之同名的变量。
5. 局部变量与全局变量名字相同的时候,这时候局部优先,但是同时又要清楚的认识到,局部变量是有自己的作用范围的,一旦超出了这个作用范围,也就是超出的那个大括号,一切都是白搭。而全局变量是永恒的
6. C程序的基本组成单位是函数,C语言本身没有输入输出语句。
7. for后面的括号里面的两个分号之间的三个数,到底该怎么去理解呢?我的建议是给它理解成起点终点,这是一种理解方式,还有一种理解方式是用循环次数的方式去理解,具体用哪种理解方式,具体问题具体分析。
8. 对指针变量进行解引用操作的本质就是通过指针变量指向的内存地址及其后的势力范围找到他内存条里面存放的数据
9. 还是前置++,还是后置++,--道理也一样,都是有副作用的。
10. *p++,由于在不加括号的情况下,++的优先级是要高于*号的,但由于这个表达式是后置++,导致这个表达式的*解引用的还是p,但是当解引用完了之后,p的值会++
题目1
代码 1
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
//
int max = (a > b ? a : b);
//
int i = 0;
for (i = max; i <= (a * b); i++)
{
if ((i % a == 0) && (i % b == 0))
{
printf("%d\n", i);
break;
}
}
return 0;
}
代码2
//1. 假设a和b的最小公倍数是m,那么就有:m / a = i, (i=1,2,3,4,5,6.......)
//2. 则m为a * i,于是乎,a * i % b == 0。
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
//
int i = 1;
while (a * i % b != 0)
{
i++;
}
printf("%d\n", a * i);
return 0;
}
代码3
//假设有两个数a和b,它们的最大公倍数和最小公约数分别为m和n,则拥有一个等式,即:a * b = m * n。
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
//
int num1 = a > b ? a : b;
int num2 = a < b ? a : b;
while (num1 % num2 != 0)
{
int rem = num1 % num2;
num1 = num2;
num2 = rem;
}
int Div = num2;
//
printf("%d\n", a * b / Div);
return 0;
}
经验总结
1. 求两个数的最大公倍数有三种方法以及更多。需要我们合理选择。
一,
1. 假设a和b的最小公倍数是m,那么就有:m / a = i。
2. 则m为a * i,于是乎,a * i / b == 0。
二,
假设有两个数a和b,它们的最大公倍数和最小公约数分别为m和n,则拥有一个等式,即:a * b = m * n。
2. 在用辗转相除法求最大公约数的时候,在最开始,两个除数的大小必须要保证num1>num2。
题目2
代码1:
#include <stdio.h>
int main()
{
char arr[1000] = { 0 };
gets(arr);
//
int sz = strlen(arr);
//
int i = 0;
for (i = (sz - 1); i >= 0; i--)
{
if ((*(arr + i - 1) == ' ')||(i==0))
{
printf("%s", arr + i);
}
if (*(arr + i) == ' ')
{
printf(" ");
*(arr + i) = '\0';
}
}
return 0;
}
代码2:
#include <assert.h>
#include <stdio.h>
void reverse(char* left, char* right)
{
assert(left && right);
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[1000] = { 0 };
gets(arr);
//
int sz = strlen(arr);
//
reverse(arr, arr + sz - 1);
//
int i = 0;
char* start = arr;
char* end = NULL;
for (i = 1; i < sz; i++)
{
if (*(arr + i - 1) == ' ')
{
start = arr + i;
}
if ((*(arr + i + 1) == ' ')||(*(arr + i + 1) == '\0'))
{
end = arr + i;
reverse(start, end);
}
}
printf("%s\n",arr);
return 0;
}
代码三(与2大同小异):
#include <assert.h>
#include <stdio.h>
void reverse(char* left, char* right)
{
assert(left && right);
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[1000] = { 0 };
gets(arr);
//
int sz = strlen(arr);
//
reverse(arr, arr + sz - 1);
//
char* cur = arr;
//
while (*cur)
{
char* start = cur;
while ((*cur != ' ') && (*cur != '\0'))
{
cur++;
}
reverse(start, cur - 1);
if (*cur != '\0')
{
cur++;
}
}
//
printf("%s\n", arr);
return 0;
}
经验总结
有时候需要巧妙利用字符数组,对其进行各种操作。如果要逆序字符串的话,可以通过左端设置一个left,右端设置一个right,然后把两者指向的内容互换位置,然后再向中间靠拢。