如果有人可以协助我参与我正在进行的当前项目,我想我会更好地理解这个概念。我想使用C来使用指针编辑特定内存地址的数据。具体来说,我有两个字符数组(字符串),我需要从特定位置读取数据,并写入特定位置。
我对指针的语法感到困惑,例如*
和->
以及&
。
根据我的理解,*
指的是保存在指针当前内存地址的数据。因此,例如,如果我想编辑char *p
的起始内存地址处的数据,我会执行以下操作:(*p) = 'c';
现在,如果我想从p
的开头改变 2nd 内存地址的字符怎么办?
另外,我知道&
指的是指针的位置。但我不知道如何使用这种语法。
以下是我的例子:
int orig_length = strlen(original_string); //-1 for \0?
char *poriginal, *pnew_string;
poriginal = &original_string;
while(orig_length>0) {
k = 0;
j = 0;
while(isalpha(*(poriginal+j))) {
j++;
k++;
}
while(k > 0) {
*(pnew_string+(j-k)) = toupper(*(poriginal+k-1)); //toupper
k--;
}
if(*(poriginal+(j)) == '_') {
*(pnew_string+(j)) = ' ';
}
else {
*(pnew_string+(j)) = *(poriginal+(j));
}
orig_length = orig_length - j;
}
*(pnew_string+strlen(pnew_string)) = '\0'; //Syn? Is this actually necessary?
... //program continues...
顺便说一下,这个程序的意思是取一个字符串“now_i_understand!”并反转每个单词,将每个单词大写,将_切换为'',并留下其他标点符号:“我是DNATSREDNU!”
答案 0 :(得分:3)
如果您正在处理的是一个字符数组(并且它是),请使用数组语法:
pnew_string[j+1] = poriginal[j+1];
请注意,此语法等同于:
*(pnew_string + j + 1) = *(poriginal + j + 1);
但更具可读性。
在这个例子中,处理大多数其他案例应该是显而易见的。
答案 1 :(得分:1)
*
和&
运算符是彼此相反的。指针对象保存内存中某个其他对象的地址(或旧的空指针,它不指向任何对象)。
一元*
运算符接受一个指针操作数,并为您提供它指向的对象;这称为解除引用。
一元&
运算符接受一个引用任何类型对象的操作数,并为您提供指向该对象的指针。 &
是地址 - 运算符。
例如:
int obj = 42; /* obj is an object of type int; it currently holds the value 42 */
int *ptr; /* ptr is a pointer to an int */
ptr = &obj; /* ptr now holds the address of obj */
printf("obj = %d\n", obj); /* prints 42 */
printf("*ptr = %d\n", *ptr); /* also prints 42; *ptr is another name for obj */
->
运算符是取消引用指针并访问其指向的成员的简写。前缀必须是指向struct或union的指针。 foo->bar
与(*foo).bar
的含义相同,其中foo
是指针,bar
是foo
指向的成员的名称。
您还可以对指针执行算术运算。如果ptr
是指向数组元素的指针,则ptr + 1
指向数组的下一个元素,ptr + 2
指向之后的元素,依此类推。
[]
数组索引操作符实际上是根据指针算法定义的。 ptr[2]
与*(ptr+2)
完全相同。将它与大多数上下文中的数组名称衰减到指向数组的第一个元素的指针这一事实相结合,稍加思考就会看到arr[2]
如何引用数组的第三个元素{{1 (第三,因为索引从arr
开始)。
我强烈推荐comp.lang.c FAQ的第4节(指针)和第6节(数组和指针);它可能会比我更好地解释这些东西。