C中的指针理解

时间:2017-05-25 21:51:47

标签: c

我在理解以下使用指针的代码时遇到了一些问题。该代码是为AVR uC ATMega328pb制作的。编写代码是为了每100ms读取0-255的正弦值,并将这些值写入比较标志。然后当Counter到达比较标志时,它启用ISR(中断服务程序),它根据0-255,255的最高亮度的比较标志使LCD变暗。

首先是正弦定义: PS。:代码工作正常

char SIN_SAMPLE_LENGTH 40;
uint8_t sinOut[] = {0, 1, 6, 13, 24, 37, 52, 69, 88, 107, 127, 147, 166, 185, 202, 217, 230, 241, 248, 253, 255, 253, 248, 241, 230, 217, 202, 185, 166, 147, 127, 107, 88, 69, 52, 37, 24, 13, 6, 1};
uint8_t *sinSample = sinOut;

我知道指针*sinSample存储了sinOut的内存地址,但不应该存在&sinOut

然后我有一个主循环

int main(void)
{
    int cnt = 0; //count
    sei();
    Init_IO();
    Init_T0();

    while(1)
    {
        if(HasOneMillisecondPassed()){ //function returns true when one millisecond passes
            cnt++; //counting up on 1ms count

            if(cnt >= 100){  // when it reaches 100ms do this
                cnt = 0; //restore count on 0

                if(sinSample >= sinOut + SIN_SAMPLE_LENGTH){ 

                    sinSample = sinOut;
                }else{
                    sinSample++;
                }

                OCR0A = *sinSample; 

            }
        }
    }
}

void Init_T0()
{
    OCR0A = *sinOut;
    TCCR0A = (1 << WGM01) | (1 << WGM00) | (1 << COM0A1) | (1 << COM0A0);
    TCCR0B= (1 << CS00) | (1 << CS01);
    TIMSK0 = (1 << OCIE0A);
}

我不理解

中的部分

if(sinSample >= sinOut + SIN_SAMPLE_LENGTH)

直到

OCR0A = *sinSample

更具体地说,sinOut + SIN_SAMPLE_LENGTH如何影响if语句以及sinSample = sinOut;的含义

谢谢!

4 个答案:

答案 0 :(得分:2)

sinSample是指向sinOut数组中当前元素的指针。当你这样做时,它开始指向数组的第一个元素:

uint8_t *sinSample = sinOut;

每次程序都这样做:

sinSample++;

它指向数组的下一个元素。

sinOut + SIN_SAMPLE_LENGTH是指向sinOut数组末尾的指针,因为SIN_SAMPLE_LENGTH是数组中元素的数量。因此,

if (sinSample >= sinOut + SIN_SAMPLE_LENGTH)

测试我们是否将指针递增到数组的末尾。发生这种情况时,代码会将其设置回数组的开头。结果是它在数组中循环。

这完全等同于使用索引变量循环遍历数组,例如

int sinIndex = 0;
while(1)
{
    if(HasOneMillisecondPassed()){ //function returns true when one millisecond passes
        cnt++; //counting up on 1ms count

        if(cnt >= 100){  // when it reaches 100ms do this
            cnt = 0; //restore count on 0

            if(sinIndex >= SIN_SAMPLE_LENGTH){ 
                sinIndex = 0;
            }else{
                sinIndex++;
            }

            OCR0A = sinOut[sinIndex]; 

        }
    }
}

在C中,这两个表达式总是等价的:

array[index]

*(array + index)

因为当一个数组在大多数表达式中用作R值时,它会衰减到指向其第一个元素的指针,并且指针算术会按指针所指向的对象的大小计算。

这是理解C指针和数组的基础,所以如果它仍然没有沉入,请返回并重读教科书中的那一章。

答案 1 :(得分:0)

  1. uint8_t *sinSample = sinOut;是正确的。或者,uint8_t *sinSample = &sinOut[0];

  2. 当指针sinSample到达sinOut缓冲区的末尾时,它被“包裹”回到开头以发出连续信号。

答案 2 :(得分:0)

这基本上是一个可互换使用的数组和指针语义的例子sinOut + SIN_SAMPLE_LENGTHsinOut[SIN_SAMPLE_LENGTH]相同。 或者,您可以将指针推进sinSample++视为sinSample[index++]

答案 3 :(得分:0)

关于你的问题:

*我知道指针 sinSample存储sinOut的内存地址,但不应该存在&amp; sinOut?

在C中,指的是数组名称降级为数组第一个字节的地址。所以这一行:

uint8_t *sinSample = sinOut;

sinOut数组的地址分配给sinSample,因此不需要address of运算符&。因此,不应使用address of运算符。