美文网首页C/C++学习
C/C++学习心得(持续更新中...)

C/C++学习心得(持续更新中...)

作者: simplson | 来源:发表于2017-11-05 23:35 被阅读0次

1. const的用法 (正确使用const将大大改善程序的健壮性)

  • const int *p; //指针p1i所指内容是常量,可以不初始化
  • int * const p; //指针p2i是常量,所指内容可修改
  • const int * const p; //指针p3i是常量,所指内容也是常量
  • 由于const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。

2. static的用法

  • 定义函数内局部静态变量
  • 定义文件内全局静态变量
  • 定义文件内静态函数
  • 定义类内静态成员变量和静态成员函数
  • 全局变量、静态全局变量以及静态局部变量都会被放在程序的静态数据存储区(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它们与栈变量、堆变量的区别。

3. virtual的用法

  • 虚拟继承
  • 实现多态(确定一个函数调用来自父类还是子类)
  • 纯虚函数
  • 虚析构函数
  • 虚函数必须实现,不实现编译器会报错

4. 动态链接库中有个全局变量,两个进程中一个进程改变这个全局变量,另一个进程中使用这个全局变量是否会改变?

答:不会改变,因为进程之间一般不共享数据,进程间通信可以通过IPC,例如共享内存等 。

5. 进程间通信方法中哪种效率最高(共享内存、套接字、管道)?

答:依具体的数据传输量来定,数据量<4500字节,共享内存效率最高;5000<数据量 <11000,套接字效率最高,11000<数据量,管道的效率最高。

6. 定义一个指针,不给它初始化赋值,为什么系统给它默认的地址为0xCCCCCCCC而不是其它的?

答:VC的Debug下是这样的,地址0x0CCCCCCCC处于内核地址空间,一般的应用程序是无权访问的,一旦访问就会报错。这样做是为了使我们在调试的时候能尽早地发现野指针,不让本该在调试阶段发现的问题从眼皮底下溜走。

6. pthread_cond_signal后为什么要加sleep才能实现线程同步?

答:对于条件变量来说,如果pthread_cond_signal之后没有任何线程阻塞在pthread_cond_wait上,那么此条件变量上的信号丢失。
解决办法:用pthread_yield()函数实现让出 线程控制权;也可以用nanosleep来代替sleep 减小休眠时间。

7. (1) map.insert(pair<char *, char *>(str1, str2)); (2) map.insert(pair<int, char *>(i, str)); 默认排序为升序, (1)中按字符串起始地址排序,(2)中按整形值排序 另外map在insert时,如果key重复,则将会替换?

答:不会替换,只是插入失败而已

vector<char *> vec_name;

for(int i = 0; i < 2; i++)
{
    char name[128] = {0};
    sprintf(name, "%s%d", "name", i);
    vec_name.push_back(name);  
}
printf("vector[0] = %s \n", vec_name[0]);
printf("vector[1] = %s \n", vec_name[1])

out:
vector[0] = name1
vector[1] = name1

   map <char *, int> map_name;
   map <char *, int>::iterator iter;

   for (int j = 0; j < 2; j++)
   {
        char key[32] = {0};
        sprintf(key, "%s%d", "name", j);
        map_name.insert ( pair <char *, int>  ( key, j ) );
   }

   for (iter = map_name.begin( ); iter != map_name.end( ); iter++)
   {
        printf(" iter->first = %s \n", iter->first);
        printf(" iter->second = %d \n", iter->second);
   }

out:
iter->first = name1
iter->second = 0

8. 自定义map中的比较函数

struct Cmp {
  bool operator()(const char *str1, const char *str2) {

        if (strcmp(str1, str2) <= 0)    return 1;  //升序,反之降序
        else return 0;
  }
};

map<char *, int, Cmp>map_name;

9. 自定义vector中的比较函数

bool cmp(char a[], char b[])
{
        if (strcmp(a, b) <= 0) return 1;    //升序
        else return 0;
}

vector<char *> clock_time
sort(clock_time.begin(), clock_time.end(), cmp);

10. 如果元素是结构体,那么,可以直接把比较函数写在结构体内。下面的程序详细说明了如何操作:

#include <map>
#include <string>
#include <iostream>

using namespace std;

struct Info
{
    string name ;
    float score ;
    //重载 “<”操作符,自定义排列规则
    bool operator < (const Info &a) const
    {
        //按score由大到小排列。如果要由小到大排列,使用“>”号即可
        return a.score < score ;
    }
};

int main()
{
    map<Info, int> m;
    Info info;
    //插入元素,按键值的由小到大放入黑白树中
    info.name = "Jack";
    info.score = 60;
    m[info] = 25 ;
    info.name = "Bomi";
    info.score = 80 ;
    m[info] = 10 ;
    info.name = "Peti";
    info.score = 66.5;
    m[info] = 30;
    map<Info,int> :: iterator it ;
    for(it = m.begin(); it != m.end(); it++)
    {
        cout << (*it).second << " : ";
        cout << ((*it).first).name << " : " << ((*it).first).score << endl;
    }
    return 0 ;
}

11. 正确使用stl map中的erase方法

  • 使用删除之前的迭代器定位下一个元素。STL建议的使用方式
      for(ITER iter=mapTest.begin();iter!=mapTest.end();)
      {
        cout<<iter->first<<":"<<iter->second<<endl;
        mapTest.erase(iter++);
      }
  • erase() 成员函数返回下一个元素的迭代器
      for(ITER iter=mapTest.begin();iter!=mapTest.end();)
      {
        cout<<iter->first<<":"<<iter->second<<endl;
        iter=mapTest.erase(iter);
      }

12. sscanf用法

char str1[64] = {0};
char str2[64] = {0};
char str3[64] = {0};
//先将 "iios/"过滤掉,再将非'@'的一串内容送到str1中
sscanf("iios/12DDWDFF@122","%*[^/]/%[^@]", str1);
sscanf("iios/12DDWDFF@122","%*[^/]/%s", str2);
sscanf("iios/12DDWDFF@122","%[^/]", str3);
printf("%s\n", str1);
printf("%s\n", str2);
printf("%s\n", str3);

out :
12DDWDFF
12DDWDFF@122
iios

        char DesiredTime[128] = {0};
        sprintf(DesiredTime, "%s", "1901-01-09 15:23:55");
        char year[16] = {0};
        char mon[16] = {0};
        char day[16] = {0};
        char hour[16] = {0};
        char min[16] = {0};
        char sec[16] = {0};
        int iYear,iMon,iDay,iHour,iMin,iSec;
        int valu;

        printf("\n DesiredTime = %s \n", DesiredTime);

        valu = sscanf(DesiredTime, "%4s-%2s-%2s %2s:%2s:%2s", year, mon, day, hour, min, sec);
        printf("valu1 = %d \n", valu);

        valu = sscanf(DesiredTime, "%d-%d-%d %d:%d:%d", &iYear,&iMon,&iDay,&iHour,&iMin,&iSec);

        printf("\n year=%s,mon=%s,day=%s,hour=%s,min=%s,sec=%s \n", year, mon, day, hour, min, sec);
        printf("\n iYear=%d,iMon=%d,iDay=%d,iHour=%d,iMin=%d,iSec=%d \n", iYear,iMon,iDay,iHour,iMin,iSec);

        printf("valu2 = %d \n", valu);

out:
DesiredTime = 1901-01-09 15:23:55
valu1 = 6
year=1901,mon=01,day=09,hour=15,min=23,sec=55
iYear=1901,iMon=1,iDay=9,iHour=15,iMin=23,iSec=55
valu2 = 6

13. C代码优化方案

  • 使用尽量小的数据类型
  • 求余运算 a=a%8改为a=a&7 通常只要是求2n方的余数,均可使用位操作的方法来代替
  • 平方运算 a=pow(a, 2.0); 改为 a=a*a;
  • 用移位实现乘除法运算 a=a4;改为a=a<<2; b=b/4;改为b=b>>2; a=a9改为a=(a<<3)+a;
  • 使用复合赋值表达式 a-=1及a+=1
  • 结构体成员的布局
  • Switch语句中根据发生频率来进行case排序
  • 函数优化(Inline函数、不定义不使用的返回值、减少函数调用参数、所有函数都应该有原型定义、尽可能使用常量(const)、把本地函数声明为静态的(static))
  • 变量(register变量、同时声明多个变量优于单独声明变量、短变量名优于长变量名,应尽量使变量名短一点、在循环开始前声明变量)

相关文章

  • C/C++学习心得(持续更新中...)

    1. const的用法 (正确使用const将大大改善程序的健壮性) const int *p; //指针p...

  • C++、数据结构、算法-读书笔记

    C++、数据结构、算法学习? Dedicate this to someone My love 持续更新中!!!!...

  • C++基础教程之C/C++区别

    C/C++基础教程之C/C++区别 这是C++教程得第一步,后续会持续更新哦!欢迎新手(具有C基础),老鸟可绕道,...

  • C++链接

    C++开源代码项目汇总 C++11之经典书籍和网文推荐(持续更新资源下载链接) 通过这 9 本开源书,学好 C++

  • 【C++】C++代码规范(持续更新)

    C++自定义函数 尽量不要用 可以这样 也可以这样

  • c++基础之函数

    距离上次更新又过了一周,又该更新新的读书笔记了。本次更新的主要是c++中函数部分的内容c++ 中的函数与c语言中的...

  • C++简明教程

    本教程旨在提取最精炼、实用的C++知识点,供读者快速学习及本人查阅复习所用,后期会持续更新。 基本语法 C++ 语...

  • C/C++ 开发总结 -- 【持续更新】

    此文章将记录我在C/C++ 开发过程中遇到的问题及相关知识技术点 ,方便自己以后查阅..... 博客原文:http...

  • C++开发心得(持续更新)

    要习惯使用智能指针,避免裸指针。 常见的智能指针有以下几种: std::shared_ptr:(1)引用计数和被管...

  • 二叉树后序非递归遍历

    我的全部数据结构(C++)代码,会持续更新:https://github.com/ylzf0000/DataStr...

网友评论

    本文标题:C/C++学习心得(持续更新中...)

    本文链接:https://www.haomeiwen.com/subject/sdfkmxtx.html