C语言基础知识和部分代码细节

菜鸟新人所作,只为方便自己回忆,如有错误,欢迎斧正!

算法

1动态规划最优子结构性质:如果问题的最优解所包含的子问题的解也是最优的。子问题重叠性质:对每一个子问题只计算一次,然后将其计算结果保存在一个表格中。无后效性:以前的各阶段状态不影响未来决策。背包动态规划复杂度为O(nc)当容量c很大时不用动态规划

1 2

C语言

一 概念

1  *和&    eg:int a = 10;    int *b = &a;

  a表示a对应的存储单元中的数据。 
&a表示a对应的存储单元的地址。 
*b表示:先要求b存储的是存储单元a的地址。 *b表示a存储单元中的数据

 附:数组本质上其实也是指针,即:*a 等同于 a[]
    函数返回数组可 设函数类型为int* fun(){ int r[] ;  return r ;}

附:const int * ptrint const * ptr完全等价,指向整型常量整型指针ptr

  int * const ptr声明了一个指向整型变量常指针ptr

例:int a[5]={1,2,3,4,5};   int *ptr=(int*)(&a+1);   printf("%d,%d",*(a+1),*(ptr-1));

 答案2,5。 &a+1不是首地址+1,系统会认为加一个a数组的偏移,ptr=&(a[5])

2  字符串:C 语言中,字符串是使用 null 字符 '\0' 终止的一维字符数组

      C++ 字符串除字符数组还可用string类

printf输出用%s  输出会逐个扫描字符,直到遇见 '\0' 才结束输出

字符串给字符数组赋值时自动添加 '\0',数组长度要比字符串长度大1字符串长度不包括 '\0'

 附: 1)使用字符数组时的库函数(C:#include <string.h> C++: #include <cstring>):

复制s2到s1: strcpy(s1, s2);  连接s2到s1: strcat(s1, s2);  长度: strlen(s1);

返回int型 s1-s2: strcmp(s1, s2);   返回指针 s1中第一次位置: strchr(s1, ch);

返回指针 s1中s2第一次出现位置: strstr(s1, s2);

  1. C++的string类 #include <string>:复制用= ;连接用+ ;长度用.size();

3 结构体:成员访问运算符(.)

如果两个结构体互相包含,则需要对其中一个结构体进行不完整声明

附:

4 typedef是在基本类型的基础上定义类型的同义字eg:typedef int a //a等同int

struct前加typedef 则最后的结构体变量名变为结构体类型名

typedef 仅限于为类型定义,#define定义类型或数值 eg:#define N 1;

typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。

5 共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值

共用体定义和 结构体类似,访问用 ( . )

6 1) 定义枚举 enum类型: 默认第一个元素为0,后续元素为前元素加一

Eg:enum season {spring, summer=3, autumn, winter};  则:spring=0,autumn=4

  1. 定义枚举变量:enum DAY day; 或类型变量同时定义enum DAY{...} day;
  2. 枚举类型连续才能遍历:eg:enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN } day;

  for (day = MON; day <= SUN; day++) { printf("%d ", day); } 输出1234567

7 1) static全局变量与普通的全局变量: 全局变量本身就是静态存储方式,当源程序由多个源文件组成,非静态全局变量在各个源文件中都有效。静态全局变量只在定义该变量的本源文件内有效。static全局变量只能初使化一次。总之改变作用域,生存期不变。

2) 静态局部变量将生存期变为整个源程序(以前退出函数消失),作用域不变

3)  static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

4) 局部变量在中,全局变量在静态区 中,动态申请数据在堆中

10 "位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域 的位数  定义和结构体相仿,成员:类型 位域名: 位域长度 (用./->访问)

11 算法更优:用>>和<<代替/和* ;用&7代替%8

12 中断服务子程序(ISR)

  1. ISR没有参数和返回值  2) 尽量不要使用浮点数处理程序

13 预编译:展开宏定义,删除注释,处理#include预编译指令,处理条件编译指令 如#id #ifdef,添加行号和文件名标识

编译:进行词法分析、语法分析、语义分析及优化后,生成汇编代码文件

汇编:将汇编代码转变成机器可以执行的指令(机器码文件)。

链接:将各个模块之间相互引用的部分正确的衔接起来。包括了地址和空间   分配、符号决议和重定向

14 C/C++内存模型

                           

 

15内存管理

内存管理MMU的作用:内存分配和回收,内存保护和扩充,地址映射 

  1. void *calloc(int num, int size);动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0;共分配了 num*size 个字节长度的内存
  1. void free(void *address); //释放内存
  2. void *malloc(int num); //在堆申请指定大小内存eg:d= (char*)malloc(sizeof(char));
  3. void *realloc(void *address, int newsize); //内存重分配

二 编码

注:vc编码快捷键:

1)注释:先CTRL+K+C ;       取消注释:先CTRL+K+U

1, Q:黑框一闪而过

A: 开头 #include<stdlib.h>    return前加 system("pause");

Q: vs报错:转换到COFF期间失败

A:项目属性-清单工具-输入输出-嵌入清单是改否

2 Q: continue与 break用法

  A: continue结束本次循环,跳过后面语句进入下一次循环,用于(while,do,for)

    Break循环结束

 3 预处理命令必须以#开头 无分号包括:宏定义,文件包含,条件编译

(程序处理顺序:预处理,编译汇编,连接)

4 字符串输入输出函数 gets() <可空格不可回车> puts()<可空格不可空字符>

Eg: char str[1000];  gets(str);(gets()将回车'\n'作为输入字符数组)

附:scanf("%s", string);(不录空格 且空格或回车'\n'仍在缓存区)

printf(“%s”,str)和puts(str)均是输出到'\0'结束,遇到空格不停,但puts(str) 会在结尾输出'\n',printf(“%s”,str)不会换行 

  字符输入输出函数<一个字符>  c=getchar()  putchar(c)

5 Q:输入int型 跳行<字符串用gets>

  A:    int ch;

        do {

            scanf("%d",&data[i]);

            i++;

        }while((ch=getchar())!='\n');

注:输入多行数据while(scanf("%d",&n)!= EOF){...}

6分割://char *strtok(char *s1, const char *s2)

                         //该函数作用是提取以s2为分隔符的字符串,并s2替换为‘\0’

                         //规定进行子调用时(即分割s1的第二、三及后续子串)第一参 数必须是NULL

                        //在每一次匹配成功后,将s1中分割出的子串位置替换为NULL(摘 下链中第一个环),因此s1被破坏了

                       //函数会记忆指针位置以供下一次调用,当查找不到s2中的字符时, 返回NULL

char *p;

p=strtok(tmp,",");

        while(p)

        {

            strcpy(s[i],p);  //复制字符串

            i++;

            p=strtok(NULL,",");

        }

比较字符串返回int型eg:strcmp(s[k],s[k+1]) if(strcmp(s[k],s[k+1])>0)

6 Q:浮点型scanf("%lf%lf",&a,&b);  printf("%lf %lf\n",a,b);  换成%f不行

  A:用double定义a 则用%lf ;  flout型 的可以用%f,也可以用%lf

7 Q:字符串数组长度  <sizeof是内存不是元素个数>

  A:#include<string.h>  char input[10000];    length = strlen(input);

8 时间之差用时分秒换算成秒再取模  eg:  minute = sum%3600/60    

second = sum%3600%60

9 结构体 typedef struct{

...}time;  time result;  result.* ==...  <*代表结构体中元素>

12代码细节

  1. char * const p; //常量指针,p值不可改;  char const * p;//指向常量的指针

13 c语言有符号数和无符号数进行比较运算时(==,<,>,<=,>=),有符号数隐式转换成了无符号数。   eg:int a=-14;  a>6;  -14的补码为1111111111110010。此数进行比较运算时,被当成了无符号数,它远远大于6

14 、库函数

        14.1 库函数<stdlib.h>

 1) 字符串转浮点型:double atof(const char *str)

 2) 字符串转int型:int atoi(const char *str)

        14.2  库函数<string.h>

1)复制s2到s1: strcpy(s1, s2); 2)连接s2到s1: strcat(s1, s2); 3)长度: strlen(s1);

4)返回int型s1-s2: strcmp(s1, s2); 5)返回指针s1中第一次位置: strchr(s1, ch);

6)返回指针 s1中s2第一次出现位置: strstr(s1, s2);

7)分隔符(s2)分隔s1成多个字符串 char *strtok(char *s1, const char *s2)

注:每次返回第一个子串的指针,从第二次调用strtok()将参数s1设置成 NULL。每次调用成功则返回指向被分割出片段的指针。

Eg:char dest[]="ab,cd,ef,c";  char* rp;  char ch[]= ",";  rp=strtok(dest, ch);     

while(NULL != rp) {  printf("dest: %s ", dest);       

 printf("rp: %s \n", rp);  rp=strtok(NULL, ch); }                        

                                                                                             

8) void *memcpy(void*str1,const void*str2 ,size_t n) //str2的n个字符复制到str1

eg∶ memcpy(d, s+11,6);//从第11个字符(r)开始复制,连续复制6个字符(runoob)

9) char*strcat(char*dest,const char*src) // src所指字符串追加到dest末尾

char*strncat(char*dest, const char*src,size_t n)//追加结尾,直到n字符长度

10) 返回字符串中字符的位置-strchr 返回包括第一个字符和之后的字符;用数组相减就行 eg∶

char*p;  p= strchr(arr,'g’);  printf("%d",p-arr);

11) 返回字符串中字符串的位置-strstr返回包括第一个字符和之后的字符;用数组相减就行 eg:

char *p; p= strstr(arr,”g”);  printf("%d",p-arr);

12) 比较字符串返回 int型eg: strcmp(s[k],s[k+1])  if(strcmp(s[k],s[k+1])>0)

   (附: A是65,a是97,差32)

        14.3库函数<ctype.h>

int isalpha(int c)  //判断是否为字母,是字母返回非0 int型

int tolower(int c);  //字母转小写字母,eg: tolower(str[i])

int toupper(int c); //字母转大写字母

  1. 常用场景

 15.1-15.5   dp、贪心、分治、回溯、dfs、bfs、

1) 动态规划最优子结构性质:如果问题的最优解所包含的子问题的解也是最优的子问题重叠性质:对每一个子问题只计算一次,然后将其计算结果保存在一个表格中。无后效性:以前的各阶段状态不影响未来决策。背包动态规划复杂度为O(nc)当容量c很大时不用动态规划。

2) 贪心算法:每一步都是当前最优解,局部最优选择,并且最终能够求得问题的整体最优解。这些子问题之间没有关联且独立的(动态规划子问题有关联)。

3) 分治:难的大问题可以分为若干规模小的相同且独立的子问题,利用子问题的解,可以合并成该问题的解。如归并排序。

4) 回溯法是对解空间的深度优先搜索。Eg:

void backtracking(参数) {  

    if (终止条件) {  

        存放结果;  

        return;  

    }  

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {  

        处理节点;  

        backtracking(路径,选择列表); // 递归  

        回溯,撤销处理结果  

    }  

}

附:法1:回溯dfs输出子集-输出无条件

vector<vector<int>>res;

    void dfs(vector<int>nums,vector<int>&path,int start)

    {

         res.push_back(path);

         for(int i=start; i<nums.size(); i++)

         {

              path.push_back(nums[i]);//做出选择

              dfs(nums,path,i+1);//递归进下一层,i+1标识下一个开始位置

            path.pop_back();//撤销选择

         }

    }

法二:递归输出子集-无for循环

vector<int> t; //存子集

void dfs(int cur, int n) {

    if (cur == n) {

        // 记录答案

        return;

    }

    // 考虑选择当前位置

    t.push_back(cur);

    dfs(cur + 1, n, k);

    t.pop_back();

    // 考虑不选择当前位置

    dfs(cur + 1, n, k);

}

5) Dfs :递归或栈,与树有关

6) Bfs:队列

8) 树的层次遍历(知每一层)

vector<vector<int>> levelOrder(TreeNode* root) {

        /* 根据函数返回值定义存储结果的变量 */

        vector<vector<int>> result;

        queue<TreeNode*> que;

        if(root != NULL) que.push(root);

        while(!que.empty()) {

              /* 计算队列的大小也即有多少个孩子 */

              int size = que.size();

              /* 定义一个临时vector 存储每一层 */

              vector<int> vec;

              for(int i = 0; i < size; i++) {  //遍历每一层

                 TreeNode* node = que.front(); //获取第一个节点数据

               que.pop();

                 vec.push_back(node->val);

                 if(node->left != NULL) que.push(node->left);

                 if(node->right != NULL) que.push(node->right);

             }

             result.push_back(vec); // /* 将一层的数据保存 */

       }

        return result;

    }

10) 辗转相除法求公因数∶

int gcd(int a,int b) { //辗转相除法

        if(a%b==0)

                return b;

        return gcd(b,a%b);

}

11) 字符串反串∶

#include(algorithm>

string str;  cin >> str;

reverse(str.begin(),str.end());

12) 找素数思路

a) 素数的倍数排除素数

b) 素数一定是6的倍数加减一,代码如下∶

int prime(int num) {

        if (num <= 3){

                return 1;

        }

        // 不在6的倍数两侧的一定不是质数

        if (num %6!=1&& num %6!= 5{

                return 0;

        }

        int s = sqrt(num); //sqrt可以对int和double开根返回double

        //int s= sqr(num, 0, num);

        for (int i= 5; i<=s; i+=6) {

                if (num%i==0 || num %(i+2)== 0){

                        return 0;

                } 

        }

        return 1;

}

16  1)文件打开 FILE *fopen( const char * filename, mode );//字符串目录和模式

mode: r//只读; w//只写,不存在则新建; a//追加模式写; (有+则允许读写)

Eg:FILE *fp = NULL; fp = fopen("/tmp/test.txt", "w+");

  1. 文件关闭fclose(文件名);
  2. 写入文件:int fputs( const char *s, FILE *fp );把字符串s写入,成功返回正 数;失败返回EOF

附: int fprintf(FILE *fp,const char *format) 写入字符串

  1. 读取文件:char *fgets( char *buf, int n, FILE *fp );读取 n - 1 个字符并在最后追加一个 null 字符来终止字符串;读取时遇到换行符 '\n' 或文件末尾 EOF,则只会返回读取到的字符,包括换行符

附:fscanf(FILE *fp, const char *format, 串名) 读取字符串,遇到空格换行符停止读取。  eg:   fscanf(fp, "%s", buff);

  1. 二进制文件读取用:fread和fwrite

17错误处理:C提供了 perror() 和 strerror() 函数来显示与 errno 相关的文本消息。

18内存管理

内存管理MMU的作用:内存分配和回收,内存保护和扩充,地址映射 

  1. void *calloc(int num, int size);动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0;共分配了 num*size 个字节长度的内存
  1. void free(void *address); //释放内存
  2. void *malloc(int num); //在堆申请指定大小内存eg:d= (char*)malloc(sizeof(char));
  3. void *realloc(void *address, int newsize); //内存重分配

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值