11月13日
c语言自带的qsort
#include<stdio.h>
#include<stdlib.h>
int comp(const void *a,const void *b)//用来做比较的函数。
{
return *(int*)a-*(int*)b;
}
int main()
{
int a[10] = {2,4,1,5,5,3,7,4,1,5};//乱序的数组。
int i;
qsort(a,10,sizeof(int),comp);//调用qsort排序
return 0;
}
从小到大排 b-a就是从大到小了
memset函数
# include <stdio.h>
# include <string.h>
int main(void)
{
int i; //循环变量
char str[10];
char *p = str;
memset(str, 0, sizeof(str)); //只能写sizeof(str), 不能写sizeof(p)
for (i=0; i<10; ++i)
{
printf("%d\x20", str[i]);
}
printf("\n");
return 0;
}
11月16日
输出最后多个换行一般会影响结果吗?否。
多组字符串输入一般还是用二维数组比较好。
但也不是绝对的,比如内存分配器那道题
数组实现栈
char contents[SIZE];
int top=0;
void push(char i){
contents[top++]=i;
}
char pop(void){
if(top==0){
printf("Empty\n");
}
else{
return contents[--top];
}
}
11月18日
寻找比大的2的幂
int two(int x){
int ans=-1;
for(int i=1;;i*=2){
ans++;
if(i>=x){break;}
}
return ans;
}
计算2的幂
1<<n就行了
11月19日
malloc函数的使用
char *b;
a=malloc(N);
b=malloc(N);
————————————————————————————————————————
IEEE754 十六进制转十进制 单精度浮点
#include <math.h>
float f(int number)
{
int sign = (number & 0x80000000) ? -1 : 1;//这里的&是按位与运算符。这里是判断符号位
int exponent = ((number >> 23) & 0xff) - 127;//先右移操作,再按位与计算,出来结果是30到23位对应的e
float m = 1 + ((float)(number & 0x7fffff) / 0x7fffff);//将22~0转化为10进制,得到对应的x
return sign * m * pow(2, exponent);
}
int main()
{
int a;
scanf("%x",&a);
float result = f(a);
printf("%f", result);
return 0;
}
如果只是为了输出正确的值,请见内存解释器
————————————————————————————————————————————
11月20日
int search(int x){
int l=0,r=n-1;//范围是k[l]到k[r]
while(r>=0&&l<n&&l<=r){
int i = (l+r+1)/2;
if(k[i]==x){
return 1;
}
else if(k[i]<x){
l=i+1;
}
else{
r=i-1;
}
}
return 0;
}
此为二分法搜索,在此之前必须从小到大排序
——————————————————————————————
void swap(int *a,int *b){
int x=*a;
*a=*b;
*b=x;
}
void sort(int l,int a[]){
for(int i=0;i<l-1;i++){
for(int j=0;j<l-i-1;j++){
if(a[j]>a[j+1]){
swap(&a[j],&a[j+1]);
}
}
}
}
此为冒泡排序
几个string.h里面的函数
char *strcpy(char *s1,const char *s2){
char *p=s1;
while (*s1++ = *s2++);
return p;
}
char *strcat(char *s1,const char *s2){
char *p = s1;
while(*p){
p++;
}
//这个地方不应该写为while(*p++)因为这会导致p多走一位
//正如数学中开闭区间容易出错,编程中的端点位置也是很容易出问题的
while(*p++ = *s2++)
;
return s1;
}
在倒水那道题里一直用的比较
#define min(a, b) ((a) < (b) ? (a) : (b))
既不需要反复写又不需要定义函数
宏是很简洁的写法
字符反转和素数检验两个函数太常用了。
int ans = 0;
while (n) { 翻转数字
ans = ans * 10 + n % 10;
n/=10;
}
return ans;
}
这个的想法是什么呢?
1234换为4321,实际是个什么过程?
4321=(410+3)10+2)*10+1
课本上提到,这种方法可以用在一切多项式函数身上。
int check(int n) {
for (int i = 2; i * i n; i)
if (n % i 0) 如果有因式,直接返回 “非素数”
return 0;
return 1;
}
while(scanf("%s",&s)!=EOF){
...
}
是个很好的读入方式
clion请在调试时键入ctrl+D以输入EOF
#include <stdlib.h>
struct node{
int n;
struct node* next;
};
struct node* addtolist(int n,struct node*list){
struct node*newnode= malloc(sizeof(struct node));
newnode->n=n;
newnode->next=list;
return newnode;
}
struct node* deletefromlist(int n,struct node*list){
struct node* cur,*prev;
for(cur=list,prev=NULL;cur!=NULL&&cur->n!=n;prev=cur,cur=cur->next){
}
if(cur==NULL)return list;
if(prev==NULL)list=list->next;
else
prev->next=cur->next;
free(cur);
return list;
}
int main(){
struct node* p;
struct node* first = NULL;
first = addtolist(114514,first);
first = addtolist(1919810,first);
for(p=first;p!=NULL;p=p->next){
printf("%d\n",p->n);
}
first = deletefromlist(1919810,first);
for(p=first;p!=NULL;p=p->next){
printf("%d\n",p->n);
}
return 0;
}
//链表最基本的操作,这里的addtolist使用的是头插法
今天学的有点多。。。
有序链表,函数指针,函数数组,太妙辣
受限指针。指针的指针。都是特殊情况下的妙计。
int (*p) [10] = malloc(sizeof(int)*200);
这种一般都是对二维数组的某一列进行操作。p是一个指针,指向一个10元数组,也就是每一行有10个元素,共有20列
p++就会到下一行的同一列。
位运算系统讲解
i&(1<<j):读取i的第j位
i &= ~(1<<j):把i的第j位设为0
i |= (1<<j):把i的第j位设为1
期末冲刺
1.复习过往的oj,并且回忆、思考当时遇到的问题
2.回忆经典算法
3.回顾经典函数(准备笔试)