C中变量和数组中的指针解引用

C中变量和数组中的指针解引用,c,arrays,pointers,variables,cs50,C,Arrays,Pointers,Variables,Cs50,我对指针有些困惑。我在下面的代码中使用了其中两个,它们正在工作,但我不能100%确定它们为什么工作 首先是 char *note = "A7"; 二是 char *octFreq[15] = {"1","55","2","110","3","220","4","440","5","880","6","1760","7","3520"}; 虽然我必须在数组之前而不是在单个变量之前使用*,但它们都可以得到每个变量的值。我只需使用note就可以获得note的值,但对于octFreq

我对指针有些困惑。我在下面的代码中使用了其中两个,它们正在工作,但我不能100%确定它们为什么工作

首先是

char *note = "A7";
二是

char *octFreq[15] = 
       {"1","55","2","110","3","220","4","440","5","880","6","1760","7","3520"};
虽然我必须在数组之前而不是在单个变量之前使用
*
,但它们都可以得到每个变量的值。我只需使用note就可以获得note的值,但对于
octFreq
,我无法这样做

这是我有点困惑的一行代码,所有代码都紧跟其后

    if(note[1] == *octFreq[x]){//WHY DO I HAVE TO DEREFERENCE octFreq and not note????

#包括
#包括
#包括
#包括
int main(void){//注释的顺序是C D E F G A B
char*note=“A7”;
//字符频率;
int-semiUpDown=0;
字符*octFreq[15]={“1”、“55”、“2”、“110”、“3”、“220”、“4”、“440”、“5”、“880”、“6”、“1760”、“7”、“3520”};
//int noteIndex[7]={1,2,3,4,5,6};
如果(注[1]='#'){
半向上向下=1;
//向上一个半音或乘以2^1/12
}否则如果(注[1]=“b”){
半上下=-1;
//降下一个半音或除以2^1/12
}
如果(semiUpDown==0){//这意味着没有平坦或锐利
如果(注意[0]!=“B”|注意[0]!=“B”){//请检查第一个字母是否为CDEFGA
如果(注意[0]='A'| |注意[0]='A'){//检查它是否是基线
对于(int x=0;x<13;x++){
//printf(“%s\n\n”,noteA[x]);
如果(注意[1]==*octFreq[x]){//为什么我必须取消引用octFreq而不是note????
//频率=*八进制频率[x+1];
//printf(“找到它:%s\n\n”,noteA[x]);
printf(“这是频率:%s\n\n”,octFreq[x+1]);
}
}    
}
}
}
}
如果(注意[1]==*octFreq[x])
仅比较单个字符,因此它适用于
A7
,但不适用于
A110
。这里需要使用strcmp,它使用
char*
来比较整个字符串。像这样的东西

if (0 == strcmp(&note[1], octFreq[x]))
索引运算符(
[]
)是从基指针值自动取消对特定整数量的引用

所以,我想解释一下。指针实际上只是一个保存内存位置的变量。此内存位置是一个特定的整数值(即
4000
9320
等)。您可以对该变量进行加、减、乘、除等操作,以获得指向指针所指向类型的有效值的新内存位置(在本例中为
char

您的第一个指针变量
note
,可以这样定义:

char* note = new char[3];
*(note + 0) = 'A';
*(note + 1) = 'F';
*(note + 2) = '\0'; \\all character arrays have an implicit null-terminator
然后,每个字符都可以引用为:
note[x]
,其中0char*note=“A7”表示已声明指向char数组的指针。因此,您可以像任何其他数组一样,通过注释[0]等访问其元素

char*octFreq[15]表示您声明了指向char指针数组的指针

octFreq[15]将到达索引15处的char指针。 *octFreq[15]将到达索引15处的字符指针所指向的字符。

char*note=“A7”//这里定义了字符数组('A','7','\0')。当您访问注释[1]时,会得到第二个符号('7')


字符*octFreq[15]={“1”、“55”、“2”、“110”、“3”、“220”、“4”、“440”、“5”、“880”、“6”、“1760”、“7”、“3520”};//这里定义了字符数组的数组。共有15个数组,每个数组都有类型char*。因此,当您访问octFreq[3]时,您将得到字符数组的第四个元素,它是字符数组的第四个元素(本例中为“110”)。然后将*应用于这个字符数组,得到该数组的第一个元素(此处为粗体->“110”),因为指向字符数组(char*)的指针实际上指向它的第一个元素。

为什么使用
注释[1]
?我想检查字符串的第二个字符。这些代码都没有意义。为什么不让一个整数数组,每个八度的频率都是
A
note
是指向char的指针。所以
注[1]
是一个字符
octFreq
是指向char的指针数组。因此,
octFreq[x]
是一个指针,
*octFreq[x]
是一个字符。您还可以将
*octFreq[x]
编写为
octFreq[x][0]
。欢迎使用堆栈溢出。请注意,在这里说“谢谢”的首选方式是投票选出好的问题和有用的答案(一旦你有足够的声誉这么做),并接受对你提出的任何问题最有用的答案(这也会给你的声誉带来一点提升)。请看这一页,也谢谢你指出这一点。我故意不使用strcmp(),因为我知道我只需要检查数字1…7,我可以使用==来比较两个chars@ndjustin20但是在你的八进制频率中有
1
110
,和
1760
,所以仅仅比较第一个字符似乎不可靠。我从来没有意识到这一点!!!看看频率和八度音阶,我很幸运。非常感谢您指出这一点!!!这很有道理!!!非常感谢您的回复@ndjustin20让你顿悟,
note
是一个指向字符串文字的指针(在只读内存中创建),而
octFreq
是一个数组或指向多个字符串文字的指针(也在只读内存中创建)谢谢David,我感谢你的建议!!!谢谢你的回复,我很感激
char* note = new char[3];
*(note + 0) = 'A';
*(note + 1) = 'F';
*(note + 2) = '\0'; \\all character arrays have an implicit null-terminator