C指针到Swift指针的转换

3

我正在尝试使用指针将一段C代码转换为Swift 3。以下是相关的C代码部分。

Float32 sampleArray[256] = { // Array is 256 Float values
0.00000, 0.00000, -0.00060, 0.00000, -0.00237, 0.00000, -0.00528 etc.etc}


float *p1, *p2, temp;
long i, bitm, j;

for (i = 2; i < 128-2; i += 2) {

    for (bitm = 2, j = 0; bitm < 256; bitm <<= 1) {
        if (i & bitm){j++;}
        j <<= 1;
    }

    if (i < j ) {
        p1 = sampleArray+i;
        p2 = sampleArray+j;
        temp = *p1;
        *(p1++) = *p2;    //Stuck from this point onwards
        *(p2++) = temp;
        temp = *p1;
        *p1 = *p2;
        *p2 = temp;
    }
}//eo for

以下是我的快速尝试。显然,使用相同类型的数组,但是用Swift语言。

var bitm:CLong
var j:CLong
var temp:Float
var p1:UnsafeMutablePointer<Float>
var p2:UnsafeMutablePointer<Float>

for i in stride(from: 2, to: 128-2, by: 2){
    j = 0
    bitm = 2;
    while bitm < 256 {
        if (i & bitm != 0){ j = j + 1}
        j = j<<1
        bitm<<=1
    }

    if (i < j){
        p1 = UnsafeMutablePointer(mutating: sampleArray)+i
        p2 = UnsafeMutablePointer(mutating: sampleArray)+j
        temp = p1.pointee
        /* looks ok up to this point*/

    }

}//eo stride

正如您所看到的,我已经做了这么多

(涉及IT技术)
*(p1++) = *p2;    

我认为这可能是使用指针移位的情况。
p1.advanced(by: 1)

任何对最后四行的帮助都将不胜感激。我注意到...
p2.pointee = somevalue

描述了需要处理的数组中的点。如果我将所有内容替换为

 sampleArray[j] = sampleArray[i] 

几行代码就能让我更接近于IT技术工作,但我想保留它们作为指针。这样我就可以更好地理解Swift中指针的工作原理。谢谢。

为了更加清晰,这里是sampleArray:

    var sampleArray:[Float] = [
        0.00000, 0.00000, -0.00060, 0.00000, -0.00237, 0.00000, -0.00528, 0.00000, -0.00931, 0.00000, -0.01440, 0.00000, -0.02052, 0.00000, -0.02762, 0.00000, -0.03566, 0.00000, -0.04460, 0.00000, -0.05443, 0.00000, -0.06502, 0.00000, -0.07634, 0.00000, -0.08836, 0.00000, -0.10101, 0.00000, -0.11424, 0.00000, -0.12799, 0.00000, -0.14238, 0.00000, -0.15703, 0.00000, -0.17203, 0.00000, -0.18733, 0.00000, -0.20286, 0.00000, -0.21858, 0.00000, -0.23470, 0.00000, -0.25063, 0.00000, -0.26657, 0.00000, -0.28247, 0.00000, -0.29827, 0.00000, -0.31392, 0.00000, -0.32979, 0.00000, -0.34501, 0.00000, -0.35993, 0.00000, -0.37450, 0.00000, -0.38868, 0.00000, -0.40242, 0.00000, -0.41569, 0.00000, -0.42904, 0.00000, -0.44126, 0.00000, -0.45289, 0.00000, -0.46390, 0.00000, -0.47426, 0.00000, -0.48394, 0.00000, -0.49365, 0.00000, -0.50193, 0.00000, -0.50945, 0.00000, -0.51621, 0.00000, -0.52219, 0.00000, -0.52738, 0.00000, -0.53176, 0.00000, -0.53621, 0.00000, -0.53900, 0.00000, -0.54096, 0.00000, -0.54212, 0.00000, -0.54246, 0.00000, -0.54199, 0.00000, -0.54169, 0.00000, -0.53965, 0.00000, -0.53684, 0.00000, -0.53327, 0.00000, -0.52895, 0.00000, -0.52392, 0.00000, -0.51918, 0.00000, -0.51276, 0.00000, -0.50570, 0.00000, -0.49800, 0.00000, -0.48971, 0.00000, -0.48084, 0.00000, -0.47144, 0.00000, -0.46251, 0.00000, -0.45212, 0.00000, -0.44129, 0.00000, -0.43005, 0.00000, -0.41844, 0.00000, -0.40650, 0.00000, -0.39520, 0.00000, -0.38269, 0.00000, -0.36996, 0.00000, -0.35704, 0.00000, -0.34396, 0.00000, -0.33078, 0.00000, -0.31752, 0.00000, -0.30506, 0.00000, -0.29174, 0.00000, -0.27845, 0.00000, -0.26523, 0.00000, -0.25210, 0.00000, -0.23910, 0.00000, -0.22698, 0.00000, -0.21432, 0.00000, -0.20187, 0.00000, -0.18967, 0.00000, -0.17775, 0.00000, -0.16612, 0.00000, -0.15538, 0.00000, -0.14439, 0.00000, -0.13376, 0.00000, -0.12350, 0.00000, -0.11364, 0.00000, -0.10418, 0.00000, -0.09514, 0.00000, -0.08693, 0.00000, -0.07873, 0.00000, -0.07097, 0.00000, -0.06366, 0.00000, -0.05679, 0.00000, -0.05038, 0.00000, -0.04467, 0.00000, -0.03911, 0.00000, -0.03400, 0.00000, -0.02931, 0.00000, -0.02504, 0.00000, -0.02118, 0.00000, -0.01772, 0.00000, -0.01477, 0.00000, -0.01203, 0.00000, -0.00964, 0.00000, -0.00758, 0.00000, -0.00583, 0.00000, -0.00437, 0.00000, -0.00322, 0.00000, -0.00225, 0.00000, -0.00149, 0.00000, -0.00093, 0.00000, -0.00052, 0.00000, -0.00026, 0.00000, -0.00011, 0.00000, -0.00003, 0.00000, 0.00000, 0.00000,]

以下是根据C代码应该输出的内容:

0.0000, 0.0000, -0.4980, 0.0000, -0.3745, 0.0000, -0.1235, 0.0000, -0.1280, 0.0000, -0.3175, 0.0000, -0.5318, 0.0000, -0.0177, 0.0000, -0.0357, 0.0000, -0.4184, 0.0000, -0.4743, 0.0000, -0.0568, 0.0000, -0.2506, 0.0000, -0.2143, 0.0000, -0.5396, 0.0000, -0.0022, 0.0000, -0.0093, 0.0000, -0.4625, 0.0000, -0.4290, 0.0000, -0.0869, 0.0000, -0.1873, 0.0000, -0.2652, 0.0000, -0.5421, 0.0000, -0.0076, 0.0000, -0.0763, 0.0000, -0.3700, 0.0000, -0.5094, 0.0000, -0.0340, 0.0000, -0.3139, 0.0000, -0.1661, 0.0000, -0.5239, 0.0000, -0.0003, 0.0000, -0.0024, 0.0000, -0.4808, 0.0000, -0.4024, 0.0000, -0.1042, 0.0000, -0.1570, 0.0000, -0.2917, 0.0000, -0.5390, 0.0000, -0.0120, 0.0000, -0.0544, 0.0000, -0.3952, 0.0000, -0.4937, 0.0000, -0.0447, 0.0000, -0.2825, 0.0000, -0.1897, 0.0000, -0.5333, 0.0000, -0.0009, 0.0000, -0.0205, 0.0000, -0.4413, 0.0000, -0.4529, 0.0000, -0.0710, 0.0000, -0.2186, 0.0000, -0.2391, 0.0000, -0.5420, 0.0000, -0.0044, 0.0000, -0.1010, 0.0000, -0.3440, 0.0000, -0.5222, 0.0000, -0.0250, 0.0000, -0.3450, 0.0000, -0.1444, 0.0000, -0.5128, 0.0000, -0.5057, 0.0000, -0.0006, 0.0000, -0.4897, 0.0000, -0.3887, 0.0000, -0.4714, 0.0000, -0.1424, 0.0000, -0.4521, 0.0000, -0.5362, 0.0000, -0.4301, 0.0000, -0.0446, 0.0000, -0.4065, 0.0000, -0.4839, 0.0000, -0.3827, 0.0000, -0.2666, 0.0000, -0.3570, 0.0000, -0.5368, 0.0000, -0.3308, 0.0000, -0.0144, 0.0000, -0.3051, 0.0000, -0.4413, 0.0000, -0.2785, 0.0000, -0.2029, 0.0000, -0.2521, 0.0000, -0.5425, 0.0000, -0.2270, 0.0000, -0.0884, 0.0000, -0.2019, 0.0000, -0.5162, 0.0000, -0.1777, 0.0000, -0.3298, 0.0000, -0.1554, 0.0000, -0.5192, 0.0000, -0.1338, 0.0000, -0.0053, 0.0000, -0.1136, 0.0000, -0.4157, 0.0000, -0.0951, 0.0000, -0.1720, 0.0000, -0.0787, 0.0000, -0.5410, 0.0000, -0.0637, 0.0000, -0.0650, 0.0000, -0.0504, 0.0000, -0.5019, 0.0000, -0.0391, 0.0000, -0.2983, 0.0000, -0.0293, 0.0000, -0.5290, 0.0000, -0.0212, 0.0000, -0.0276, 0.0000, -0.0148, 0.0000, -0.4639, 0.0000, -0.0096, 0.0000, -0.2347, 0.0000, -0.0058, 0.0000, -0.5417, 0.0000, -0.0032, 0.0000, -0.1142, 0.0000, -0.0015, 0.0000, -0.5274, 0.0000, -0.0005, 0.0000, -0.3599, 0.0000, -0.0001, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000,
3个回答

2

你的代码中有一个非常糟糕的问题:

UnsafeMutablePointer(mutating: sampleArray)

请查看使用手册中的指针部分

常量指针

...

传递给函数的指针仅在函数调用期间被保证有效。不要尝试持久化指针并在函数返回后访问它。

因此,传递给UnsafeMutablePointer.init(mutating:)的指针在初始化程序调用之后可能无效。当然,返回的指针也可能无效。

如果要在闭包内使用保证在其中有效的指向Swift数组的指针,则需要将sampleArray声明为var并使用withUnsafeMutableBufferPointer(_:)

sampleArray.withUnsafeMutableBufferPointer {bufferPointer in
    let sampleArrayPointer = bufferPointer.baseAddress!
    for i in stride(from: 2, to: 128-2, by: 2) {
        var j: CLong = 0
        var bitm: CLong = 2
        while bitm < 256 {
            if i & bitm != 0 { j += 1 }
            j <<= 1
            bitm <<= 1
        }

        if i < j {
            // p1 = sampleArray+i;
            var p1 = sampleArrayPointer + i
            // p2 = sampleArray+j;
            var p2 = sampleArrayPointer + j
            // temp = *p1;
            var temp = p1.pointee
            // *(p1++) = *p2;
            p1.pointee = p2.pointee
            p1 += 1
            // *(p2++) = temp;
            p2.pointee = temp
            p2 += 1
            // temp = *p1;
            temp = p1.pointee
            // *p1 = *p2;
            p1.pointee = p2.pointee
            // *p2 = temp;
            p2.pointee = temp
        }
    }//eo stride}
}

但是,正如Codo的答案所建议的那样,在这种情况下,您不需要使用指针。


1
你的C代码只是使用指针来访问数组元素。在C和Swift中都不需要使用指针。这种C代码风格可能在30年前更快。但是今天它会阻止编译器有效地使用寄存器。
好消息是:我们不需要指针,可以轻松将其转换为Swift。你卡住的代码只是交换了i / j和i + 1 / j + 1处的元素。
var sampleArray: [Float] = [
    0.00000, 0.00000, -0.00060, 0.00000, -0.00237, 0.00000, -0.00528, 0.00000, -0.00931, 0.00000, -0.01440, 0.00000, -0.02052, 0.00000, -0.02762, 0.00000, -0.03566, 0.00000, -0.04460, 0.00000, -0.05443, 0.00000, -0.06502, 0.00000, -0.07634, 0.00000, -0.08836, 0.00000, -0.10101, 0.00000, -0.11424, 0.00000, -0.12799, 0.00000, -0.14238, 0.00000, -0.15703, 0.00000, -0.17203, 0.00000, -0.18733, 0.00000, -0.20286, 0.00000, -0.21858, 0.00000, -0.23470, 0.00000, -0.25063, 0.00000, -0.26657, 0.00000, -0.28247, 0.00000, -0.29827, 0.00000, -0.31392, 0.00000, -0.32979, 0.00000, -0.34501, 0.00000, -0.35993, 0.00000, -0.37450, 0.00000, -0.38868, 0.00000, -0.40242, 0.00000, -0.41569, 0.00000, -0.42904, 0.00000, -0.44126, 0.00000, -0.45289, 0.00000, -0.46390, 0.00000, -0.47426, 0.00000, -0.48394, 0.00000, -0.49365, 0.00000, -0.50193, 0.00000, -0.50945, 0.00000, -0.51621, 0.00000, -0.52219, 0.00000, -0.52738, 0.00000, -0.53176, 0.00000, -0.53621, 0.00000, -0.53900, 0.00000, -0.54096, 0.00000, -0.54212, 0.00000, -0.54246, 0.00000, -0.54199, 0.00000, -0.54169, 0.00000, -0.53965, 0.00000, -0.53684, 0.00000, -0.53327, 0.00000, -0.52895, 0.00000, -0.52392, 0.00000, -0.51918, 0.00000, -0.51276, 0.00000, -0.50570, 0.00000, -0.49800, 0.00000, -0.48971, 0.00000, -0.48084, 0.00000, -0.47144, 0.00000, -0.46251, 0.00000, -0.45212, 0.00000, -0.44129, 0.00000, -0.43005, 0.00000, -0.41844, 0.00000, -0.40650, 0.00000, -0.39520, 0.00000, -0.38269, 0.00000, -0.36996, 0.00000, -0.35704, 0.00000, -0.34396, 0.00000, -0.33078, 0.00000, -0.31752, 0.00000, -0.30506, 0.00000, -0.29174, 0.00000, -0.27845, 0.00000, -0.26523, 0.00000, -0.25210, 0.00000, -0.23910, 0.00000, -0.22698, 0.00000, -0.21432, 0.00000, -0.20187, 0.00000, -0.18967, 0.00000, -0.17775, 0.00000, -0.16612, 0.00000, -0.15538, 0.00000, -0.14439, 0.00000, -0.13376, 0.00000, -0.12350, 0.00000, -0.11364, 0.00000, -0.10418, 0.00000, -0.09514, 0.00000, -0.08693, 0.00000, -0.07873, 0.00000, -0.07097, 0.00000, -0.06366, 0.00000, -0.05679, 0.00000, -0.05038, 0.00000, -0.04467, 0.00000, -0.03911, 0.00000, -0.03400, 0.00000, -0.02931, 0.00000, -0.02504, 0.00000, -0.02118, 0.00000, -0.01772, 0.00000, -0.01477, 0.00000, -0.01203, 0.00000, -0.00964, 0.00000, -0.00758, 0.00000, -0.00583, 0.00000, -0.00437, 0.00000, -0.00322, 0.00000, -0.00225, 0.00000, -0.00149, 0.00000, -0.00093, 0.00000, -0.00052, 0.00000, -0.00026, 0.00000, -0.00011, 0.00000, -0.00003, 0.00000, 0.00000, 0.00000
]

var i = 2
while i < 256 - 2 {

    var bitm = 2
    var j = 0

    while bitm < 256 {
        if (i & bitm) != 0 {
            j += 1
        }
        j <<= 1
        bitm <<= 1
    }

    if i < j {
        swap(&sampleArray[i], &sampleArray[j])
        swap(&sampleArray[i + 1], &sampleArray[j + 1])
    }

    i += 2
}

最好使用 swap(_:_:) - Alexander
我已经在原始帖子中添加了输入数组和我认为的输出结果。我不确定它们是否匹配。 - oldman
1
我已经修复了编译错误,并使用了swap(正如@AlexanderMomchliov所建议的)。我只比较了前大约30个数值,它们似乎匹配。 - Codo
@oldman:我的代码输出与您在问题中展示的不同。但是您的C代码输出也是如此,我也运行了它。有趣的是,我的Swift代码的输出似乎与C代码的输出匹配。 - Codo
参考输出显示可能是使用for (i = 2; i < 256-2; i += 2)生成的,而不是128-2。请尝试将您的128 - 2更改为256 - 2 - OOPer
显示剩余2条评论

1
在C语言中,p1++对应于Swift中的p1.successor()p1.advanced(by: 1)
*(p1++)

在C语言中,“获取指针对应的值”意味着从指针中获取该值。
p1.successor().pointee  

在Swift中
所以代码的其余部分将会是:
 if (i < j){

        p1 = UnsafeMutablePointer(mutating: sampleArray)+i
        p2 = UnsafeMutablePointer(mutating: sampleArray)+j
        temp = p1.pointee
        /* looks ok up to this point*/

        p1.successor().pointee  = p2.pointee
        p2.successor().pointee = temp
        temp = p1.pointee
        p1.pointee = p2.pointee
        p2.pointee = temp
    }

我之前从未听说过“successor”这个代码,虽然它很棒,但并不能完全满足我的需求,因为其他值都应该是零。但它确实给了我一些希望。我会回报的,谢谢。 - oldman
我觉得 swap 函数在那里可能会有用。 - Sulthan
@Sulthan,原帖作者只是想将C指针转换为Swift指针。如果您去查看问题历史记录,就会发现。 - LC 웃

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接