TIPS
1. 当创建数组的时候,如果没有指定数组的元素个数也没关系,编译器会根据你初始化的内容来自行确定。
2. 在逻辑表达式当中,如果为真,就以1作为结果,如果为假,就以0作为结果。
3. 输入字符串的时候,可以用scanf加上%s,但是这么弄有一个缺陷,就是说scanf一旦读到空格就会停下来(有\n的话也会继续读下去),这就导致在输入字符串的时候,如果想要完整读入,就不能有空格。而gets()读取字符串的时候就没有那么多事了,并且还会把最后输入的一个\n自动从入缓冲区里面拿掉。
4. 指针的核心在于进行解引用操作,解引用操作!bty,指针(变量)与地址与内存编号这三个概念完全等价!
5. 比如说一个函数返回值是一个数组,那么其实我们知道,在代码里面数组名就是首元素的地址,其实也相当于就是返回了一个指针,于是在定义函数的时候开头比如说是int *。
6. 每一次函数调用,都需要在内存的栈区上为该函数开辟一块内存空间,事实上也就是该函数的函数栈帧。
7. 寄存器是电脑当中独立于内存的存储介质,常见的有eax, ebx,ecx,edx,ebp,esp等等,其中,ebp与esp这两个寄存器很关键。
1. 首先这两个寄存器里面放的是地址。
2. 其次这两个寄存器一个维护栈顶,一个维护栈底。
3. 这两个寄存器指向的位置=在维护的位置=里面放的地址=寄存器的值。
8. 每压一次栈,esp指向的位置就会发生变化。
9. 内存栈区的使用习惯是先使用高地址,在使用低地址,由高向低不断蔓延
10.strlen与printf在操作字符串时,\0都是不统计在内,而sizeof则不一样,字符串末尾的\0也是统计在内。
11. 不完全初始化的时候,其他位置默认初始化为0;静态区里面的值(如全局变量)就算不初始化,也默认为0.
12. 在C语言中,非0表示真,0表示假。逻辑表达式为真则为1,逻辑表达式为假则为0.
13. 尤其要注意,在除/时,如果两边操作数都为整数的话,执行的是整数除法,这时候就算你用double类型的数据去接受结果,也无非白添了小数点加6个0。当两边其中一个操作数为浮点数时,才执行小数除法,用double类型去接受结果才能如你所意。
14. #define定义常量与宏的时候不需要在末尾加;号。在代码里面就无脑替换就可以了,举个例子:
题目1
代码1:
/**
*
* @param rotateArray int整型一维数组
* @param rotateArrayLen int rotateArray数组长度
* @return int整型
*/
int minNumberInRotateArray(int* rotateArray, int rotateArrayLen )
{
int left=0;
int right=rotateArrayLen-1;
while(left<right)
{
int mid=(left+right)/2;
if (*(rotateArray+mid)>*(rotateArray+right))
{
left=mid+1;
}
else if (*(rotateArray+mid)<*(rotateArray+right))
{
right=mid;
}
else
{
right--;
}
}
return *(rotateArray+left);
}
经验总结:
1. 数组有关问题利用双指针指向首尾做为区间的端点是个常见的操作。
2. 像这道题可以用二分法的思路(同样经常运用在查找当中),旋转数组将原本有序的数组分成了两部分有序的数组,在原始有序数组中,最小的元素一定是在首位,现在相当于切断成了两部分,并且旋转了一下,我们可以将旋转前的前半段叫A,后半段叫B,现在相当于由原先的AB变成了BA。那么就可以知道:那个切点一定是数组的最小值所在。
3. 这时候就把中间值与端点值进行比较,发现:
1. 若是区间中点值大于区间右界值,则最小的数字一定在中点右边。
2. 若是区间中点值等于区间右界值,则是不容易分辨最小数字在哪半个区间,比如[1,1,1,0,1],应该逐个缩减右界。
3. 若是区间中点值小于区间右界值,则最小的数字一定在中点左边。
4. 于是就用二分法调整区间,最后就可以锁定最小值所在。
代码2:
/**
*
* @param rotateArray int整型一维数组
* @param rotateArrayLen int rotateArray数组长度
* @return int整型
*/
int minNumberInRotateArray(int* rotateArray, int rotateArrayLen )
{
int i=0;
for (i=1;i<rotateArrayLen;i++)
{
if (*(rotateArray+i)<*(rotateArray+i-1))
{
return *(rotateArray+i);
}
}
return *(rotateArray);
}
经验总结:
1. 再怎么旋转,这也是一个数组,我们要找的数组最小值,更通用的解法莫过于遍历数组。
题目2
答案:8
经验总结:
1. 像这样define定义的常量与宏,都是可以去进行替代的,但是尤其要注意的一点就是,不能用数学的惯性给它随意加上括号(),如下面这样就是大错特错的
2. 而应该是这样才对:
题目3
设变量已正确定义,以下不能统计出一行中输入字符个数(不包含回车符)的程序段是( )
答案:D
经验总结:
1. 这是for循环的执行流程图:for (exp1 ; exp2 ; exp3),是先执行exp1,然后判断exp2,为真的话再执行循环体,再执行exp3,然后在进行判断。
2. getchar()可以用来读取一个字符(你输入的),它的返回值是读取到的那个字符的ASCII码。
3. 当程序执行时一旦出现getchar,如果此时输入缓冲区里面没有东西,就会弹出一个界面,让你去输入字符(它读取不到就会返回EOF)。如果此时输入缓冲区里面有东西,那么getchar对抓去它干它自己的活。一次只能读取一个字符。
题目4
代码:
#include <stdio.h>
#include <string.h>
int Judge(char* arr)
{
//条件2
if ((*arr>=48)&&(*arr<=57))
{
return 0;
}
//条件4
if (strlen(arr)<8)
{
return 0;
}
//条件3
int flag1=0;
int flag2=0;
int flag3=0;
while(*arr!='\0')
{
if ((*arr>=48)&&(*arr<=57))
{
flag1=1;
}
else if ((*arr>=65)&&(*arr<=90))
{
flag2=1;
}
else
{
flag3=1;
}
int sum=flag1+flag2+flag3;
if (sum>=2)
{
return 1;
}
arr++;
}
return 0;
}
int main()
{
//输入n
int n=0;
scanf("%d",&n);
//循环n次
int i=0;
char arr[100]={0};
for (i=0;i<n;i++)
{
//输入字符串
scanf("%s",arr);
if (Judge(arr))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}
经验总结:
1. 在计算机代码里面,可以用简单的数字来表达一个事件的发生与否与状态。比如这边就定义flag1,flag2, flag3即使如此。