常用基本知识(总)

编程的时候通常会用到的基本代码、知识

编程注意事项

注意事项一:确保程序的时间复杂度,尽量提升程序的速度,这也要求了不同程序使用不同的算法.
注意事项二:确保程序的简洁性,注重程序中注释的使用。

基本知识

一、数学知识

1、素数

素数是指除1以外,只能被自身整除的数
注意:1不是素数,素数的反例是质数

2、阶乘 Factorial

C n m = n ! m ! ( n − m ) ! C_n^m=\frac{n!}{m!(n-m)!} Cnm=m!(nm)!n!

A n m = n ! ( n − m ) ! = n ∗ ( n − 1 ) ∗ . . . ∗ ( n − m + 1 ) A_n^m=\frac{n!}{(n-m)!}=n*(n-1)*...*(n-m+1) Anm=(nm)!n!=n(n1)...(nm+1)

MAX值:int型对应12!,long long对应20!

1!  = 1
2!  = 2
3!  = 6
4!  = 24
5!  = 120
6!  = 720
7!  = 5040
8!  = 40320
9!  = 362880
10! = 3628800
11! = 39916800
12! = 479001600					//MAX int
13! = 6227020800
14! = 87178291200
15! = 1307674368000
16! = 20922789888000
17! = 355687428096000
18! = 6402373705728000
19! = 121645100408832000
20! = 2432902008176640000
	  1234567890123456789		//MAX long long int

3、斐波那契数列

一般递推式:

F(1)=1				F(2)=1					F(n)=F(n-1)+F(n-2)

一般会用到其变式~
数列值的另一种求法: F n = [ ( 1 + 5 2 ) n ] Fn=[(\frac{1+\sqrt{5}}{2})^n] Fn=[(21+5 )n]
其中[x]表示取距离x最近的整数。
应用一:台阶
有一段楼梯有10级台阶,规定每一步只能跨一级或两级,要登上第 10 级台阶有几种不同的走法?
这就是一个斐波那契数列:登上第一级台阶有一种登法;登上两级台阶,有两种登法;登上三级台阶,有三种登法;登上四级台阶,有五种登法……
应用二:兔子繁殖
一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么一年以后可以繁殖多少对兔子?
1 1 2 3 5 8…

4、矩阵的幂

矩阵的0次幂
除了矩阵的对角线上的元素值为1外,其他元素全部为0

二、计算机知识

各种类型的范围及输入输出关键字

Tips:C语言中整性最大精度为long long:9223372036854775807; 共19位

1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19
9	2	2	3	3	7	2	0	3	6	8	5	4	7	7	5	8	0	7
类型最小值最大值输入关键字输出关键字字节数/byte二进制
char-128128%c%c127
short-3276732768%hd-2215
unsigned short065536%hu-2216
int-21474836482147483647%d%d4231
unsigned int04294967295%u%u4232
long long-92233720368547758089223372036854775807%l64d-8263
unsigned long long0264%lld-8264
float-3.40282e+0383.40282e+038%f%f8
double-1.7×103081.7×10308%lf%f8

ASCII码表

在这里插入图片描述

三、日常知识

1、国际象棋布局
横:a b c d e f g h 共8行
纵:1 2 3 4 5 6 7 8 共8列

编程基本知识

1. 输出随机数的四种方式

前提:头文件包含stdlib.h
第一种:输出0~RAND_MAX之间的随机数
magic = rand();
第二种:输出num1~num2之间的随机数 num1、num2可以输入或者随机指定
int num1=100,num2=0; magic = rand()%num1+num2;
第三种:通过输入关键字来决定输出num1~num2之间的随机数
int seed=...; srand(seed); magic = rand()%num1+num2;
第四种:通过时间来控制输出num1~num2之间的随机数
srand(time(NULL)); magic rand()%num1~num2;
注意:头文件必须包含time.h

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//这三个头文件必不可少
int main()
{
	printf("Three means of outputing a random number.\n");
	//随机数函数: rand() 
	int magic = 0, seed = 0;
	//输出0~RAND_MAX之间的随机数
	magic = rand();
	printf("num_1: 0~RAND_MAX——%d\n", magic);
	//输出num1~num2之间的随机数
	int num1 = 0, num2 = 100;
	magic = rand() % num2 + num1;
	printf("num_2: num1(%d)~num2(%d)——%d\n", num1, num2, magic);
	//通过键入关键字seed,输出0~100之间的随机数
	printf("enter a number(seed): ");
	scanf_s("%d", &seed);
	srand(seed);
	magic = rand() % 100 + 0;
	printf("num_3: seed = %d , 0~100——%d\n", seed, magic);
	//通过时间来控制输出随机数
	srand(time(NULL));
	magic = rand() % 100 + 0;
	printf("num_4: time control 0~100——%d\n", magic);
	return 1;
}

2. 浮点数存储的具体数值

1、凡是可以直接转换为int型的float型而不丢失信息的数据,都是以整数存储。
但是存在小数的浮点数,存储的时候会发生误差。
2、如果想要判断两个浮点数是否相等,则应预定义一个很小的数,用是否在某个数为中心的区间内来判断两个数是否相等。

int FloatNumber(void)
{
	double f1 = 0.1, f2 = 0.0, f3 = 0, f4 = 1.0;
	printf("%.20f  %.20f  %.20f  %.20f\n", f1,f2,f3,f4);
	return 1;
}

输出为:
在这里插入图片描述

3. switch case 的语法:

switch(表达式)
{
     case1:
     	表达式的值和值1匹配上了,需要执行的代码;
       	break;
     case2:
       	表达式的值和值2匹配上了,需要执行的代码;
     	break;
     case3:
       	表达式的值和值3匹配上了,需要执行的代码;
     	break;
     default:
       	如果表达式的值和以上的case后面的值都没有匹配上,那么就执行这里的代码。
       	break;
}

break的作用是阻值下面的case的继续运算,妙用break可以事半功倍!

4. realloc的用法:

前提:需要有一个指针,如void* p;
p=(void*)malloc(sizeof(void*)*initial_size);——对指针p申请sizeof(void*)*initial_size大小空间;
在指针p的空间基础上,从指针p的开始位置申请大小为sizeof(void*)new_size的空间
p=(void*)realloc(p,sizeof(void*)new_size);
new_size=0; realloc的作用相当与free
0<new_size<intial_size时,realloc将会将原来的数据域的部分数据删除,造成数据流失
new_size=intial_size时,没有变化
new_size>initial_size时,将会在原先的空间的基础上,多申请new_size-initial_size的空间
注:malloc/calloc/realloc用法

5. 宏定义使用

宏即是在程序中无条件的用后面替换前面
示例1:交换两个数

#include<stdio.h>
#define change(a,b) t=a;a=b;b=t;
int main()
{
    int a,b,t;
    scanf("%d%d", &a,&b);
    change(a,b);
    printf("%d %d", a,b);    
    return 0;
}

change(a,b)后面的“;”可加可不加,因为宏定义的替换语句中,最后加上了“;”,如果宏定义中有加上分号,则在主函数中必须加上“;”。
注意:因为宏定义是无条件替换,所以在进行运算或者编译检查的过程中,要进行替代,检查出其中可能存在的错误,避免造成不必要的错误。
示例2:在三个实数中求出最大的那个数

#include<stdio.h>
#define Max(a,b,c) (a>b?a:b<c?c:a>b?a:b)
int main()
{
    float a,b,c;
    scanf("%f%f%f", &a,&b,&c);
    printf("%.3f\n", Max(a,b,c));
    return 0;
}

上述代码并没有编译报错。
编译报错的错误代码是:#define Max(a,b,c) (a>b?a:a=b>c?a:c)
报错的地方是赋值的那一句,报错原因为lvalue required as left operand of assignment,即左操作数需要赋值
但是我不知道到底是什么原因编译器报错,暂且就这么理解:宏定义不能将两个参数进行赋值

6. 快速排序 Quick Sort

快速排序的用法:
头文件:stdlib.h
函数:void qsort(void *base, size_t nitems, size_t size, int (*compare)(const void *, const void*))
base-- 指向要排序的数组的第一个元素的指针。
nitems-- 由 base 指向的数组中元素的个数。
size-- 数组中每个元素的大小,以字节为单位。
compare-- 用来比较两个元素的函数,即函数指针(回调函数)
对于函数compare的两种排序方式:递增,递减(非)

//from small to large
int compare(const void* a,const void* b)
{
	return *(int *)a-*(int *)b;
}
//from large to small
int compare(const void* a,const void* b)
{
	return *(int *)b-*(int *)a;
}
//application
qsort(array_base, n, sizeof(array_base), compare);
array_base-->array
sizeof(array_base)-->the size of array array_base

7. scanf返回值

读取成功任何一个元素,返回值从零自增一。
全部读取失败:返回值为-1;
文件结束:返回值为-1;

8. 去除数组中相同的元素

1、使用冒泡排序法,将相同的元素用最后一个元素覆盖,位置不变,元素数量减一。

#include <stdio.h>
int main()
{
	int i,j,t,a[N];
	for(i=0;i<k;i++){
        for(j=0;j<N-i-1;j++){
            if(a[j]>a[j+1]){
                t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
                j--;
            }
            if(a[j]==a[j+1]){
                a[j+1]=a[N-1];
                j--;
                N--;
            }
        }
    }
}

9. scanf对字符串的读取

1、对字符串读取的时候,%s%d类似,读取缓冲区的内容,如果遇到空格或者换行符,跳过继续读取,直到非空格或着换行符才存取,直到空格或者换行符结束。
2、对%c来说,非常特殊,' '(space)和\n(回车)都是字符,所以在读取的时候,会将缓冲区中之前或者当前的空格或回车读取。
3、如果想要使用%s%c读取除了回车或者空格外的字符,则应在%c前面加上
scanf(" %c", &c);

#include<stdio.h>
#include<string.h>
/**测试scanf对字符串读取后缓冲区的情况**/
int main()
{
    char s[10],c;
    //scanf("%s%c", s,&c);
    //scanf(" %s%c", s,&c);
    scanf(" %s %c", s,&c);
    printf("s=%s   c=:%c:", s,c);
    return 0;
}
/*****测试结果*****
scanf格式:scanf("%s%c", s,&c);
样例一:
读取:123 4
输出:s=123   c=: :
样例二:
读取: 123 4
输出:s=123   c=: :
scanf格式:scanf(" %s%c", s,&c);
样例一:
读取:123 4
输出:s=123   c=: :
样例二:
读取: 123 4
输出:s=123   c=: :
scanf格式:scanf("%s %c", s,&c);
样例一:
读取:123 4
输出:s=123   c=:4:
样例二:
读取: 123 4
输出:s=123   c=:4:
********************/

10、字符串

string.h中相关的函数
一个变量类型
size_t:无符号整型(unsigned int),是sizeof操作符返回的结果类型,在64位系统中为long unsigned int
一个宏
NULL:空指针常量的值
以str开头的函数
size_t strlen(const char *str)
计算字符串str的长度,直到空结束字符",不包括空结束字符。
char*strcpy(char *dest,const char *src)
把src所指向的字符串复制到 dest。
char*strncpy(char *dest,const char *src,size_t n)
同上,把src所指向的字符串的前n个字符复制到dest。
char*strcat(char *dest,const char*src)
把src所指向的字符串追加到dest所指向的字符串的结尾,实现字符串的连接。
char*strncat(char*dest,const char*src,size_t n)
同上,把src所指字符串的前n个字符添加到dest所指字符串的结尾处,并覆盖dest所指字符串结尾的",实现字符串的连接。
char*strchr(const char*str,int c)
在参数str所指向的字符串中搜索第一次出现字符C(无符号字符)的位置,如果5tr中没有c,则返回NULL。
char*strrchr(const char *str,int c)
在参数str所指向的字符串中搜索最后一次出现字符C(无符号字符)的位置,如果str中没有c,则返回NULL。
int strcmp(const char *str1,const char *str2)
把str1所指向的字符串和str2所指向的字符串进行比较,当str1<str2时,返回一个负数;当str1==str2时,返回零;当str1>str2时,返回一个正数。
int strncmp(const char *str1,const char *str2,size_t n)
同上,把str1所指字符串的前n个字符和str2进行比较。
以mem开头的函数
void*memcpy(void*dest,const void*src,size_t n)
从src复制n个字符到dest。
int memcmp(const void *str1,const void *str2,size_t n)
把str1和str2的前n个字节进行比较,其返回值与strcmp相同。
void*memset(void *str,int c,size_t n)
复制字符c(无符号字符)到参数str所指向的字符串的前n个字符。
void*memchr(const void *str,int c,size_t n)
在参数str所指向的字符串的前n个字节中搜索第一次出现字符C(无符号字符)的位置。

11、 转化为二进制(含负数补码)

转化为32为二进制(负数补码)

void Binary(int n,int a[])
{
	int i=0, j, t=n, flag=1;
	if(n<0)	n*=-1;
	while( n ){
		a[++i] = n%2;
		n/=2;
	}//读入数组
	//对负数进行补码处理
	if(t<0){
		for(i=1;i<=31;i++)
			a[i]=a[i]? 0:1;//取反
		a[32]=1;
		a[1]+=1;
		for(i=1;i<33;i++)
			if(a[i]>1){
				a[i]-=1;
				a[i+1]+=1;
			}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值