• 在C语言中, 当const修饰一个表示符的时候, 被修饰的表示符依然是一个变量, 但它具有常属性, 不能被改变. 

  • C语言中, 一些重要的关键字( Keyword ) , volatile ( 保证内存的可见性, 防止编译器对代码优化 ), typedef( 类型重命名 ),register( 寄存器关键字, 建议的作用 ) https://blog.csdn.net/21aspnet/article/details/257511

  • 全局变量的作用域为整个工程 , static修饰静态变量可以延长生命周期 , 局部变量存放在栈区 , 动态,内存分配存放在堆区 , 静态局部变量全局变量存放在静态区 , 被static修饰的变量的作用域只能在原范围内使用

  • bool值和零比较, 在C语言中bool值的语义 : 0表示假 , 1表示真, 

#define FALSE 0
#define TRUE  1

int flag;
i(flag)//为真
{
      //. . .
}
if(!flag) //为假
{
    //. . .
}
  • 浮点型和零比较, 有些浮点数在内存中无法精确的存储, 这样可能会造成精度的丢失. 一旦丢失那么就有可能计算的不够准确. 因此无法使用 == 来直接比较浮点数与零. 我们可以设置一个能接受的精度, 保证误差在精度的范围内就可以了 . 
#define EXP 0.0000000001
float f = 0.0000001;
if((f > -EXP)&&(f < EXP))
{
    //就意味着f是无限接近0的数字,约等于0
}
//如果要比较一个浮点数是否等于20.0
#define EXP 0.0000000001
float f = 0.0000001;
if(((f-20.0) > -EXP)&&((f-20.0) < EXP)))
{
    //就意味着f是无限接近0的数字,约等于0
}

 

  • break和continue在while循环中的作用, break是永久终止循环, 直接跳到循环外边. continue是终止本次循环, 就是在本次循环中continue后边的代码不会执行, 而是直接跳到while语句的判断部分, 进行下一次循环的入口判断. 

  • srand(unsigned)time(NULL)  如果用户在使用rand()函数前没有调过srand(unsigned)time(NULL), 那么系统默认将1作为随机数的初始值, 如果给了一个值, 那么每次rand()产生的随机数序列一样, 简单的理解就是保证rand()生成数的随机性

  • 左移操作符 ( << ) : 左边丢弃, 右边补零 . 相当于乘二 右移操作符( >> ) : 左边用原该值的符号位填充, 右边丢弃 . (大部分的右移相当于除二) , 特殊情况 num = -1;-1在内存中是以补码的形式存储, 补码为32个1, 

  • 右移操作符,如果数子字是正数,则右移之后在最左边补n个0,如果数字是负数,则右移之后在最左边补n个1;

  • 相关题目:二进数一的个数:将一个整数减去1之后在和原来的整数做与运算,得到的结果相当于是把整数的二进制表示中的最后一个1变成了0,所以当这个整数的二进制有多少个1,就会做多少个与运算

  • 求一个整数中二进制1的个数  * 1 : 取余判断是否为1,在除二( 缺陷当判断数为 -1 )   ** 2 : 位运算每次与1相与判断是否为1, 然后再右移,   *** 3 : 每次与它本身减一相与

  • 不创建临时变量交换两个数 1 : m n  m=m+n n=m-n m=m-n    2 : m n m=m^n n=m^n m=m^n

  • 逗号表达式 , 从左向右依次执行 . 整个表达式的结果是最后一个表达式的结果 .

  • 闰年的判断条件 : 1、能整除4且不能整除100  2、能整除400         ((a % 4 == 0) && (a % 100) != 0) || (a % 400 == 0)

  • strcpy 字符串拷贝( 注意常量不能被改变 )  strlen 字符串长度

  • 条件编译  防止头文件被重复引用

#ifndef _TEST_H_
#define _TEST_H_
//头文件的内容
#endif   //_TEST_H_
  • 大端存储模式 : 是指数据的低位字节序保存在内存的高地址中, 而数据的高位字节序, 保存在内存的低地址中;

  • 小端存储模式 : 是指数据的低位字节序保存在内存的低地址中, 而数据的高位字节序, 保存在内存的高地址中;

int Check_key()
{
    union
    {
        int i;
        char j;
    }un;
    nu.i=1;
    return un.j;
}
int Check_key()
{
    int i=1;
    return *(char *)&i;
}
  • 非递归求第n个斐波那锲数

  • strlen  计算字符串大小

// 计数器方法
int my_strlen(const char * str)
{
        int count = 0;
        while(*str)
        {
            count++;
            str++;
         }
         return count;
}
//不创建临时变量
int my_strlen(const char * str)
{
        if(*str == '\0')
                return 0;
        else
                return 1+my_strlen(str+1);
}
//指针-指针的方式
int my_strlen(char *s)
{
        char *p = s;
        while(*p !='\0')
              p++;
       return p-s;
}
  • strcpy   从src地址开始且含有'\0'结束符的字符串复制到以dst开始的地址空间,返回值的类型为char*。
char *my_strcpy(char *dest, const char*src)
 {
       char *ret = dest;
       assert(dest != NULL);
       assert(src != NULL);
       while((*dest++ = *src++))
            ;
       return ret;
}
  • strcat  将两个字符连接起来
char *my_strcat(char *dest, const char *src)
{
        char *ret=dest;
        assert(dest);
        assert(src);
        while(*dest)
        {
                dest++;
        }
        while((*dest++ = *src++))
        {
                ;
        }
        return ret;
}
  • strstr 判断str2是否是str1的子串, 如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。
char *my_strstr(const char* str1, const char* str2)
{
    assert(str1);
    assert(str2);
    char *cp=(char *)str1;
    char *substr=(char *)str2;
    if(*str2=='/0')
        return NULL;
    while(*cp)
    {
        s1=cp;
        substr=str2;
        while(*s1&&*substr&&(*s1==*substr))
        {
            s1++;
            substr++;
        }
        if(*substr=='\0')
            return cp;
        cp++;
        }
}
  • strcmp  比较字符串的大小  若str1==str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。
int my_strcmp(const char * src, const char * dst)
{
    int ret=0;
    while(!(ret=*(unsighed char *)src-*(unsigned char *)dst)&&*dst)
        src++,dst++;
    if(ret<0)
        ret=-1;
    else if(ret>0)
        ret=1;
    return ret;
}
  • memcpy  内存拷贝 函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dst所指的内存地址的起始位置中。void * ( 无类型指针, 可以接受任何类型 )   size_t  ( 字节数 )
void * my_memcpy(void * dst, const void *src, size_t count)
{
    void * ret=dst;
    while(count--)
    {
        //定义字符型,一个字节一个字节进行拷贝
        *(char *)dst=*(char *)src;
        dst=(char *)dst+1;
        src=(char *)src+1;
    }
    return ret;
}
  • memmove   用于从src拷贝count个字节到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。
void * my_memmove(void *dst, const void *src, size_t count)
{
    void * ret=dst;
    //如果目标区域与源区域有重叠的部分,从后往前拷贝,
    //若没有重叠的部分,从前往后拷贝
    if(dst<=src||(char *)dst >=((char *)src+count)){
        while(count--){
            *(char *)dst=*(char *)src;
            dst=(char *)dst+1;
            src=(char *)src+1;
        }
    }
    else{
        dst=(char *)dst+count-1;
        src=(char *)src+count-1;
        while(count--){
            *(char *)dst=*(char *)src;
            dst=(char *)dst-1;
            src=(char *)src-1;
        }
    }
    return ret;
}

 

10-15 04:34