ios判断程序是否处于调试状态

5954次浏览

当一个应用被调试的时候,会给进程设置一个标识(P_TRACED),我们可以通过检测该进程是否有设置这个标识来检测进程是否正在被调试以保护好我们的应用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <sys/types.h>
#include <sys/sysctl.h>
 
static int check_debugger( ) __attribute__((always_inline));
 
static int check_debugger( )
{
    size_t size = sizeof(struct kinfo_proc);
    struct kinfo_proc info;
    int ret,name[4];
 
    memset(&info, 0, sizeof(struct kinfo_proc));
 
    name[0] = CTL_KERN;
    name[1] = KERN_PROC;
    name[2] = KERN_PROC_PID;
    name[3] = getpid();
 
    if((ret = (sysctl(name, 4, &info, &size, NULL, 0)))){
        return ret;  //sysctl() failed for some reason
    }
 
    return (info.kp_proc.p_flag & P_TRACED) ? 1 : 0;
}

如果你不确信产生的目标代码以inline的方式编译该函数,你也可以将其转化成宏的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define DEBUGGER_CHECK {                                \
    size_t size = sizeof(struct kinfo_proc);            \
    struct kinfo_proc info;                             \
    int ret,name[4];                                    \
                                                        \
    memset(&info, 0, sizeof(struct kinfo_proc));        \
                                                        \
    name[0] = CTL_KERN;                                 \
    name[1] = KERN_PROC;                                \
    name[2] = KERN_PROC_PID;                            \
    name[3] = getpid();                                 \
                                                        \
    if(ret = (sysctl(name, 4, &info, &size, NULL, 0))){ \
        return (EXIT_FAILURE);                          \
    }                                                   \
                                                        \
    if(info.kp_proc.p_flag & P_TRACED){                 \
        /* Code to react to debugging goes here */      \
    }                                                   \
}

C++的STL是如何实现算法和数据结构分离的

456次浏览

STL看起来是使用了面向对象,但实际上是大部分都是面向过程了。
STL的很多算法,就拿sort函数来说吧。

1
void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp);

只要数据结构的跌代器是随机访问的就可以使用。比如vector, list,同时也兼容普通数组int[]。

这里说到跌代器,STL有一整套跌代器的实现标准:
1、实现begin和end函数,是要全局的
如vecotr:

1
vecotr<T>::Iterator begin(vecotr<T>);

而不是 vecotr的成员函数begin,这点要区分。
2、跌代器实现前至++运算
3、跌代器实现 * 运算
4、跌代器实现 != 运算

基本这四点就可以完成了,可以根据这个规则自己实现一个跌代器。

有了跌代器后,那么对于算法来说他们基本就一样了,开头,结尾,自增,以次访问就可以了。

所以一个sort就可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vecotr<int> a;
string b;
list<float> c;
 
sort(a.begin(), a.end());
sort(b.begin(),b.end());
sort(c.begin(),c.end());
 
static bool less(int a1, int a2)
{
    return a1 < a2;
}
 
sort(a.begin(), a.begin()+5, less); // 对前5个排序
sort(a.begin(), a.end(), less);
sort(a.begin(), a.end(), [](int a1, int a2) {
    return a1 <= a2; // 匿名函数
});

结论就是算法跟数据结构是通过跌代器进行沟通的,所以学好跌代器,STL才算学好,要会用,也要懂为原理。

最新ios设备标签与设备型号的对应关系

1164次浏览

1.这种是在较高层次获取设备类型,返回的是 iPhone , iPod , iPad 。适合要求不高的。

1
NSString *deviceType = [[UIDevice currentDevice] model];

2.这是Linux中获取设备类型的方法,主要是C语言的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <sys/types.h>
#include <sys/sysctl.h>
 
- (NSString *)getDeviceVersionInfo
{
    size_t size;
    // get the length of machine name
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    // get machine name
    char *machine = malloc(size);
    sysctlbyname("hw.machine", machine, &size, NULL, 0);
    NSString *platform = [NSString stringWithFormat:@"%s", machine];
    free(machine);
 
    return platform;
}
1
2
3
4
5
6
7
8
9
10
#include <sys/utsname.h>
 
- (NSString *)getDeviceVersionInfo
{
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *platform = [NSString stringWithFormat:@"%s", systemInfo.machine];
 
    return platform;
}

  
通过,如上方式即可获取到设备的型号信息,具体对应关系如下,

iPhone

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
	iPhone8,1		iPhone6s
	iPhone8,2		iPhone6s-plus
	iPhone8,4		iPhone5se
	iPhone7,1		iPhone6-plus
	iPhone7,2		iPhone6
	iPhone6,1		iPhone5s
	iPhone6,2		iPhone5s
	iPhone5,1		iPhone5(移动,联通)
	iPhone5,2		iPhone5(移动,电信,联通)
	iPhone5,3		iPhone5c
	iPhone5,4		iPhone5c
	iPhone4,1		iPhone4S
	iPhone3,1		iPhone4(移动,联通)
	iPhone3,2		iPhone4(联通)
	iPhone3,3		iPhone4(电信)
	iPhone2,1		iPhone3GS
	iPhone1,2		iPhone3G
	iPhone1,1		iPhone

iPad

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
	iPad1,1			iPad1
	iPad2,1			iPad2(Wifi)
	iPad2,2			iPad2(GSM)
	iPad2,3			iPad2(CDMA)
	iPad2,4			iPad2(32nm)
	iPad2,5			iPadmini(Wifi)
	iPad2,6			iPadmini(GSM)
	iPad2,7			iPadmini(CDMA)
	iPad3,1			iPad3(Wifi)
	iPad3,2			iPad3(CDMA)
	iPad3,3			iPad3(4G)
	iPad3,4			iPad4(Wifi)
	iPad3,5			iPad4(4G)
	iPad3,6			iPad4(CDMA)
	iPad4,1			iPadAir
	iPad4,2			iPadAir
	iPad4,3			iPadAir
	iPad4,4			iPadmini2
	iPad4,5			iPadmini2
	iPad4,6			iPadmini2
	iPad4,7			iPadmini3
	iPad4,8			iPadmini3
	iPad4,9			iPadmini3
	iPad5,1			iPadmini4
	iPad5,2			iPadmini4
	iPad5,3			iPadAir2
	iPad5,4			iPadAir2
	iPad6,3			iPadPro(9.7inch)
	iPad6,4			iPadPro(9.7inch)
	iPad6,7			iPadPro(12.9inch)
	iPad6,8			iPadPro(12.9inch)

iPod、AppleTV、AppleWatch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	iPod6,1			iPodtouch6
	iPod5,1			iPodtouch5
	iPod4,1			iPodtouch4
	iPod3,1			iPodtouch3
	iPod2,1			iPodtouch2
	iPod1,1			iPodtouch
 
	AppleTV2,1		AppleTV2
	AppleTV3,1		AppleTV3
	AppleTV3,2		AppleTV3
	AppleTV5,3		AppleTV4
 
	Watch1,1		AppleWatch
	Watch1,2		AppleWatch

使用参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
- (NSString*) getDeviceName
{
    NSString *deviceString = [self getDeviceVersionInfo]
 
    NSArray *modelArray = @[
 
                            @"i386", @"x86_64",
 
                            @"iPhone1,1",
                            @"iPhone1,2",
                            @"iPhone2,1",
                            @"iPhone3,1",
                            @"iPhone3,2",
                            @"iPhone3,3",
                            @"iPhone4,1",
                            @"iPhone5,1",
                            @"iPhone5,2",
                            @"iPhone5,3",
                            @"iPhone5,4",
                            @"iPhone6,1",
                            @"iPhone6,2",
 
                            @"iPod1,1",
                            @"iPod2,1",
                            @"iPod3,1",
                            @"iPod4,1",
                            @"iPod5,1",
 
                            @"iPad1,1",
                            @"iPad2,1",
                            @"iPad2,2",
                            @"iPad2,3",
                            @"iPad2,4",
                            @"iPad3,1",
                            @"iPad3,2",
                            @"iPad3,3",
                            @"iPad3,4",
                            @"iPad3,5",
                            @"iPad3,6",
 
                            @"iPad2,5",
                            @"iPad2,6",
                            @"iPad2,7",
                            ];
    NSArray *modelNameArray = @[
 
                                @"iPhone Simulator", @"iPhone Simulator",
 
                                @"iPhone 2G",
                                @"iPhone 3G",
                                @"iPhone 3GS",
                                @"iPhone 4(GSM)",
                                @"iPhone 4(GSM Rev A)",
                                @"iPhone 4(CDMA)",
                                @"iPhone 4S",
                                @"iPhone 5(GSM)",
                                @"iPhone 5(GSM+CDMA)",
                                @"iPhone 5c(GSM)",
                                @"iPhone 5c(Global)",
                                @"iphone 5s(GSM)",
                                @"iphone 5s(Global)",
 
                                @"iPod Touch 1G",
                                @"iPod Touch 2G",
                                @"iPod Touch 3G",
                                @"iPod Touch 4G",
                                @"iPod Touch 5G",
 
                                @"iPad",
                                @"iPad 2(WiFi)",
                                @"iPad 2(GSM)",
                                @"iPad 2(CDMA)",
                                @"iPad 2(WiFi + New Chip)",
                                @"iPad 3(WiFi)",
                                @"iPad 3(GSM+CDMA)",
                                @"iPad 3(GSM)",
                                @"iPad 4(WiFi)",
                                @"iPad 4(GSM)",
                                @"iPad 4(GSM+CDMA)",
 
                                @"iPad mini (WiFi)",
                                @"iPad mini (GSM)",
                                @"ipad mini (GSM+CDMA)"
                                ];
    NSInteger modelIndex = - 1;
    NSString *modelNameString = nil;
    modelIndex = [modelArray indexOfObject:deviceString];
    if (modelIndex >= 0 && modelIndex < [modelNameArray count]) {
        modelNameString = [modelNameArray objectAtIndex:modelIndex];
    }
 
    NSLog(@"----设备类型---%@",modelNameString);
    return modelNameString;
}

c++字节压缩ByteData

1369次浏览

不管什么语言,一个变量至少要占1个字节(Byte),像char,bool,byte类型都是占1个字节,无符号的范围是0~255,有符号是-128~127。

在特殊情况下,当明确知道取值范围小于0~255,如0~3。这时候就会考虑怎么能再压缩内存。因为实际用不到1个字节,只用2个位(bit)即可,但只占2位的的类型是没有的。也许你会问,这省了这么点内存有什么用,即使使用int也没有什么大不了的。

对的,当只有一个两个的时候是不需要考虑,不过当面临大数组,成百上千,甚至上万个的时候,2个位跟1个字节相差了4倍,可以节省3/4的内存,压缩75%还是很可观的。

还有一种情况是数据库对二进制数据存储是有长度限制的,做服务器的话都知道用户数据上会有大量的0~1标记,这时候使用字节压缩1个用户就会节省87.5%的储存或内存。1w个,10w个用户那节省的可不是一点点了。

好了,不多说了,核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 读取函数
// @param data 存放二进制数据
// @param eachBit 每eachBit个bit位代表一个值
// @param index 获取指定索引位置的值
int get(const vector<unsigned char>& data, int eachBit, int index)
{
    int length = (int)data.size();
    int i = (index * eachBit) / 8;
    int  m = (index * eachBit) % 8;
    unsigned int mask = (0x01 << eachBit) - 0x01;
 
    if (i < 0 || i >= length || m < 0) {
        return 0;
    }
 
    return (data[i] & (mask << m)) >> m;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 设置函数
// @param data 存放二进制数据
// @param eachBit 每eachBit个bit位代表一个值
// @param index 指定要修改的索引位置
// @param value 新的值
void set(vector<unsigned char>& data, int eachBit, int index, int value)
{
    int length = (int)data.size();
    int i = (index * eachBit) / 8;
    int  m = (index * eachBit) % 8;
    unsigned int mask = (0x01 << eachBit) - 0x01;
 
    if (i < 0 || i >= length || m < 0) {
        return ;
    }
 
    mask = mask << m;
    value = value << m;
 
    // assert(value == (value & mask));
 
    data[i] = (data[i] & ~mask) | (value & mask);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 样例
#include<stdio.h>
#include<vector>
using namespace std;
 
int main()
{
    vector<unsigned char> data = {34, 2, 57, 123, 65, 93, 33};
 
    int a = get(data, 2, 8);
    set(data, 2, 8, a+1);
    int b = get(data, 2, 8);
 
    printf("a=%d b=%d \n", a, b);
}
1
2
// 打印结果
a=1 b=2

上面为通用算法代码,下面的是用c++对代码进行了包装,增加[]访问及迭代器的操作
点击下载:ByteData.zip

如何提高 C/C++ 编程能力

289次浏览

一万小时定律:作家格拉德威尔在《异类》一书中指出:人们眼中的天才之所以卓越非凡,并非天资超人一等,而是付出了持续不断的努力。1万小时的锤炼是任何人从平凡变成超凡的必要条件。
他将此称为“一万小时定律”。要成为某个领域的专家,需要10000小时,按比例计算就是:如果每天工作八个小时,一周工作五天,那么成为一个领域的专家至少需要五年

c/c++尤其适合这句话,如果下定决心要学c/c++,那么就不要有速成的思想

1、多敲代码,多思考
2、多敲代码,多思考
3、多敲代码,多思考

以上3点就是提高c/c++编程能力最捷径的方法了!!

编程提升技巧:

1、重写算法,选一个算法(如排序),查看并敲写所有现有的算法。然后思考有没有更好的办法,或者换一个写法会怎么,能不能再优化一些,也可以基于其中的某一个算法思考。
2、编写大型项目,大型项目跟小项目完全是两码事,会遇到各种各样的问题,在解决问题中会锻炼代码编写的能力,及思维能力。
3、参与不同类型的项目开发,不同项目会有不同项目的需求及问题,可以拓展眼界范围。
4、学习开发模式
5、学习其它编程语言(如java,c#,lua,js,php等),了解其中的优缺点。
6、总之,多敲代码,多思考

蓝溪阁,一段历史 ——《遗迹之塔》

511次浏览

【蓝溪阁,一段历史 (一)】

【蓝溪阁,一段历史 (二)】

【蓝溪阁,一段历史 (三)】

【蓝溪阁,一段历史 (四)】

【蓝溪阁,一段历史 (五)】

【蓝溪阁,一段历史 (六)】

【蓝溪阁,一段历史 (七)】

【蓝溪阁,一段历史 (八)】

 

64af63cd83ee47e2b07aacf096b7de54