- 博客(72)
- 资源 (1)
- 收藏
- 关注
转载 ELF文件-符号表
目标文件中的"符号表"(symbol table)中所包含的信息用于定位和重定位程序中的符号定义和符号引用;目标文件中的其它部分通过一个符号在这个表中的索引值来使用该符号;索引值从0开始计数,但值为0的索引表项(即第一项)并没有实际的意义,它表示未定义的符号;用常量STN_UNDEF来表示未定义的符号; 符号表项(Symbol Table Entry)的格式使用结构体Elf32_Sym/
2017-07-05 09:13:56
917
原创 (转)内存对齐问题
结构体的内存布局依赖于CPU、操作系统、编译器及编译时的对齐选项。结构体内部成员的对齐要求,结构体本身的对齐要求。最重要的有三点 (一)成员对齐。对于结构体内部成员,通常会有这样的规定:各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。但是也可以看到,有时候某些字段如果严格按照大小紧密排列,根本无法达到这样的目的,因此有时候必须进行padding。各成员
2015-09-08 17:17:21
468
原创 (转)内核线程和用户线程的区别
内核级线程切换由内核控制,当线程进行切换的时候,由用户态转化为内核态。切换完毕要从内核态返回用户态;可以很好的利用smp,即利用多核cpu。windows线程就是这样的。 用户级线程内核的切换由用户态程序自己控制内核切换,不需要内核干涉,少了进出内核态的消耗,但不能很好的利用多核Cpu,目前Linux pthread大体是这么做的。 线程的实现可以分为两类:用户级线程(User-Level T
2015-09-08 17:17:19
518
原创 (转)同一进程中的线程究竟共享哪些资源
线程共享的环境包括:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。 进程拥有这许多共性的同时,还拥有自己的个性。有了这些个性,线程才能实现并发性。这些个性包括: 1.线程ID 每个线程都有自己的线程ID,这个ID在本进程中是唯一的。进程用此来标识线程
2015-09-08 17:17:16
148
转载 strcpy 函数的实现
原型声明:extern char *strcpy(char *dest,const char *src); 头文件:string.h 功能:把从src地址开始且含有‘\0’结束符的字符串赋值到以dest开始的地址空间 说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 返回指向dest的指针。strcpy不处理内存域重叠
2015-09-08 17:17:12
353
原创 strcat 函数的实现
原型 extern char *strcat(char *dest,char *src); 用法 #include 功能 把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。返回指向dest的指针。 说明 src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 举例
2015-09-08 17:17:10
533
原创 strstr 函数的实现
strstr函数:返回主串中子字符串的位置后的所有字符。 #include const char *my_strstr(const char *str, const char *sub_str) { for(int i = 0; str[i] != '\0'; i++) { int tem = i; //tem保留主串中的起始判断下标位置
2015-09-08 17:17:07
351
原创 函数模板与模板函数
1.函数指针——指针函数 函数指针的重点是指针。表示的是一个指针,它指向的是一个函数,例子: int (*pf)(); 指针函数的重点是函数。表示的是一个函数,它的返回值是指针。例子: int* fun(); 2.数组指针——指针数组 数组指针的重点是指针。表示的是一个指针,它指向的是一个数组,例子: int (*pa)[8]; 指针数组的重点是数组。表示的是一个数组,它包含的元素是指
2015-09-08 17:17:04
525
原创 内核态和用户态
核心态和用户态是操作系统两种运行级别。 核心态就是拥有资源较多的状态,或者说访问资源多的状态,也称之为特权态;相对来说,用户态就是非特权态,访问资源将受到限制。 核心态下CPU可执行任何指令,而用户态下CPU只能执行非特权指令。当CPU处于核心态时可随意进入用户态;而处于用户态时,切换到核心态只有在系统调用和中断时才能发生。一般程序一开始都是运行与用户态,当程序需要系统资源时,就必须通过中断进
2015-09-08 17:17:02
506
原创 C++ 中 typename
声明template参数时, 前缀关键字class和typename可以互换; 使用关键字typename标识嵌套从属类型名称, 但不需在基类列表和成员初始化列表内使用. 从属名称(dependent names): 模板(template)内出现的名称, 相依于某个模板(template)参数, 如T t; 嵌套从属名称(nested dependent names):从属名称在class
2015-09-08 17:16:57
372
原创 死锁及处理
所谓死锁就是一个进程集合中的多个进程因为竞争资源,而造成的互相等待现象。很显然,如果没有外力的作用,那么死锁涉及到的各个进程都将永远处于封锁状态。 产生死锁的原因主要是:(1) 因为系统资源不足。(2) 进程运行推进的顺序不合适。(3) 资源分配不当等。 死锁的必要条件: 互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。 请求与保持条件(H
2015-09-08 17:16:52
461
原创 C 运算符优先级
优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 () 圆括号 (表达式)/函数名(形参表) . 成员选择(对象) 对象.成员名
2015-09-08 17:16:50
353
原创 阻塞与非阻塞,同步与异步
1 老张把水壶放到火上,立等水开。(同步阻塞) 老张觉得自己有点傻 2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞) 老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。 3 老张把响水壶放到火上,立等水开。(异步阻塞) 老张觉得这样傻等意义不大 4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了
2015-09-08 17:16:46
293
原创 同步函数与异步函数
依据微软的MSDN上的解说: (1) 同步函数:当一个函数是同步执行时,那么当该函数被调用时不会立即返回,直到该函数所要做的事情全都做完了才返回。 (2) 异步函数:如果一个异步函数被调用时,该函数会立即返回尽管该函数规定的操作任务还没有完成。 (3) 在一个线程中分别调用上述两种函数会对调用线程有何影响呢? 当一个线程调用一个同步函数时(例如:该函数用于完成写文件
2015-09-08 17:16:43
402
原创 C 结构体位域
位域 : 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几 个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一
2015-09-08 17:16:41
329
原创 C++ 友元函数
1、为什么要引入友元函数:在实现类之间数据共享时,减少系统开销,提高效率 c++利用friend修饰符,可以让一些你设定的函数能够对这些保护数据进行操作,避免把类成员全部设置成public,最大限度的保护数据成员的安全。 具体来说:为了使其他类的成员函数直接访问该类的私有变量 即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数(友元函数不是类
2015-09-08 17:16:36
952
原创 线性结构和非线性结构
线性结构是一个有序数据元素的集合。 其中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。 常用的线性结构有:线性表,栈,队列,双队列,数组,串。 非线性结构中各个数据元素不再保持在一个线性序列中,每个数据元素可能与零个或者多个其他数据元素发生联系。根据关系的不同,可分为层次结构和群结构。 常见的非线性结构有:二维数组,多维数组,广义
2015-09-08 17:16:34
35888
原创 C++ 中指针与引用的区别
指向不同类型的指针的区别在于指针类型可以知道编译器解释某个特定地址(指针指向的地址)中的内存内容及大小,而void*指针则只表示一个内存地址,编译器不能通过该指针所指向对象的类型和大小,因此想要通过void*指针操作对象必须进行类型转化。 ★ 相同点: 1. 都是地址的概念; 指针指向一块内存,它的内容是所指内存的地址; 引用是某块内
2015-09-08 17:16:30
273
原创 内联函数与虚函数
如果函数已经被声明为inline, 内联函数已经在编译期间它的调用点上就被展开; 而虚拟函数调用的决定则要等到运行时刻在执行程序内部的每个调用点上系统根据被调用对象的实际基类或派生类的类型来决定选择哪一个虚拟函数实例. 内联不是强制性的,你只是向编译器提出这个建议,允许它在可以内联的时候采取内联形式。而虚函数本身就是一个函数,只是在多态的情况下,它要到执行时才能确定调用的函数,所以这样的
2015-09-08 17:16:27
546
原创 运算符重载详解
一般运算符重载 在进行对象之间的运算时,程序会调用与运算符相对应的函数进行处理,所以运算符重载有两种方式:成员函数和友元函数。成员函数的形式比较简单,就是在类里面定义了一个与操作符相关的函数。友元函数因为没有this指针,所以形参会多一个。 // 运算符重载,这里又叫赋值函数 string& operator =(const string &other); // 运算符重载,但这里要用
2015-09-08 17:16:23
696
原创 C++ 抽象类
一、纯虚函数定义 纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”二、引入原因:1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。 为了解决上述问题,
2015-09-08 17:16:18
751
原创 volatile 关键字
就象大家更熟悉的const一样,volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个
2015-09-08 17:16:16
236
原创 C++ 强制类型转换
C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是: TYPE b = (TYPE)a C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。 const_cast,字面上理解就是去const属性。 static_cast,命名上理解是静态类型转换。如int转换成char。(基本类型转换) dynamic_cas
2015-09-08 17:16:13
476
原创 HTTP详解2-请求、响应、缓存
1. HTTP请求格式 做过Socket编程的人都知道,当我们设计一个通信协议时,“消息头/消息体”的分割方式是很常用的,消息头告诉对方这个消息是干什么的,消息体告诉对方怎么干。HTTP协议传输的消息也是这样规定的,每一个HTTP包都分为HTTP头和HTTP体两部分,消息体是可选的,而消息头是必须的。每当我们打开一个网页,在上面点击右键,选择“查看源文件”,这时看到的H
2015-09-08 17:16:11
397
原创 HTTP详解1-工作原理
1. HTTP简介 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。 在了解HTTP如何工作之前,我们先了解计算机
2015-09-08 17:16:09
400
原创 C++ 基本知识
无论父类与子类的析构函数是否是virutal,子类的析构函数都会调用父类的析构函数 调用构造函数是与构造函数顺序相反,先子类后基类,否则如果基类先析构,子类的有些资源已经不存在了,会出错。 在C++中,类的成员变量的初始化顺序只与变量在类中的声明顺序有关,因为成员变量的初始化次序跟变量在内存中的次序有关,而内存中的排列顺序早在编译期就根据变量的定义次序决定了。从全局看,变量的初始化
2015-09-08 17:16:03
270
原创 (转)c++类的成员函数存储方式(是否属于类的对象)---一道面试题引发的思考
昨天去面试一家公司,面试题中有一个题,自己没弄清楚,先记录如下: class D { public: void printA() { cout"printA"endl; } virtual void printB() { cout"printB"endl; } }; main函数调用:
2015-09-08 17:15:59
484
原创 C++ inline
内联函数相对于宏的区别和优点: 宏是在预处理时进行的机械替换,内联是在编译时进行的。内联函数是真正的函数,只是在调用时,没有调用开销,像宏一样进行展开。内联函数会进行参数匹配检查,相对于带参数的宏有很好的优点,避免了处理宏的一些问题。宏无法进行调试。 inline 1、产生背景 写函数的好处:第一,它使程序更可读;第二,它使这段代码可以重复使用。但是,它也有缺点:当它被频繁地调用的时候
2015-09-08 17:15:57
340
原创 C++ sort函数
(一)为什么要用c++标准库里的排序函数 Sort()函数是c++一种排序方法之一,学会了这种方法也打消我学习c++以来使用的冒泡排序和选择排序所带来的执行效率不高的问题!因为它使用的排序方法是类似于快排的方法,时间复杂度为n*log2(n),执行效率较高! (二)c++标准库里的排序函数的使用方法 I)Sort函数包含在头文件为#include的c++标准库中,调用标准库里的排序方法可以不
2015-09-08 17:15:54
434
原创 最小的k个数
1 // 最小的k个数.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include 6 #include set> 7 #include 8 #include 9 using namespace std; 10 11 // set中默认是从大到小的顺序,即最先取出的是最
2015-09-08 17:15:50
318
原创 快速排序
快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试,包括像腾讯,微软等知名IT公司都喜欢考这个,还有大大小的程序方面的考试如软考,考研中也常常出现快速排序的身影。 总的说来,要直接默写出快速排序还是有一定难度的,因为本人就自己的理解对快速排序作了下白话解释,希望对大家理解有帮助,达到快速排序
2015-09-08 17:15:47
246
原创 当你在浏览器地址栏输入一个URL后回车,将会发生的事情
原文:http://igoro.com/archive/what-really-happens-when-you-navigate-to-a-url/ 作为一个软件开发者,你一定会对网络应用如何工作有一个完整的层次化的认知,同样这里也包括这些应用所用到的技术:像浏览器,HTTP,HTML,网络服务器,需求处理等等。 本文将更深入的研究当你输入一个网址的时候,后台到底发生了一件件什么样的事~
2015-09-08 17:15:38
359
原创 (转)前置++和后置++的区别
今天在阅读《google c++ 编程风格》的文档的时候,5.10. 前置自增和自减:有一句话引起了我的注意: 对于迭代器和其他模板对象使用前缀形式 (++i) 的自增, 自减运算符.,理由是 前置自增 (++i) 通常要比后置自增 (i++) 效率更高。于是我查了查前置++和后置++的区别。 注意:《more effective c++》条款8也专门叙述了问题。后来我发现,下面的文章基本就是
2015-09-08 17:15:35
1220
原创 C++默认参数
在C++中,可以为参数指定默认值。在函数调用时没有指定与形参相对应的实参时, 就自动使用默认参数。默认参数的语法与使用:(1)在函数声明或定义时,直接对参数赋值。这就是默认参数;(2)在函数调用时,省略部分或全部参数。这时可以用默认参数来代替。 注意:(1)默认参数只可在函数声明中设定一次。只有在没有函数声明时,才可以在函数定义中设定。(#add ,此句意为存在函数声明和定义两部分的时候。验证表
2015-09-08 17:15:31
438
原创 C++中对象初始化
在C++中对象要在使用前初始化,永远在使用对象之前先将它初始化。 1.对于无任何成员的内置类型,必须手工完成此事。 例如: int x=0; double d; std::cin>>d; 2.内置对象以外的东西,初始化责任落在构造函数身上。确保每一个构造函数都将对象的每一个成员初始化。 例如:
2015-09-08 17:15:27
805
原创 类设计者的核查表
1.你的类需要一个构造函数吗 需要构造函数来隐藏类的内部工作方式。 2.你的数据成员是私有的吗 通常使用公有的数据成员不是什么好事,因为类设计者无法控制何时访问这些成员。 3.你的类需要一个无参的构造函数吗 为了可生成对象数组或类的对象不必显示的初始化类的构造函数,必须显示地写一个无参的构造函数。 4.是不是每个构造函数初始
2015-09-08 17:15:24
507
原创 函数返回数组
这个问题属于非常初级的问题,但是对于初学不知道的人可能会比较头疼。C++中函数是不能直接返回一个数组的,但是数组其实就是指针,所以可以让函数返回指针来实现。比如一个矩阵相乘的函数,很容易地我们就写成: #include using namespace std; float* MultMatrix(float A[4], float B[4]) { float M[4
2015-09-08 17:15:22
433
原创 堆栈问题
编写C++中的两个类 一个只能在栈中分配空间 一个只能在堆中分配。 解答: (1)代码如下 #include using namespace std; //只能在堆上分配内存 class HeapOnly { public: HeapOnly() { cout"Construct."e
2015-09-08 17:15:19
334
原创 拷贝构造函数与赋值函数的区别
1.从概念上区分:复制构造函数是构造函数,而赋值操作符属于操作符重载范畴,它通常是类的成员函数 2.从原型上来区分:复制构造函数原型ClassType(const ClassType &);无返回值赋值操作符原型ClassType& operator=(const ClassType &);返回值为ClassType的引用,便于连续赋值操作 3.从使用的场合来区分:复制构造函数用于产生对象,它
2015-09-08 17:15:17
1102
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人