C语言指针的相关总结
第一部分:p与*p
*p
:表示解引用指针p
,可以获取p
所指向的内存地址处存储的值。通过解引用操作符(),可以访问指针p所指向的内存地址中存储的数据。
例如,如果p是一个指向int类型的指针,那么*p表示获取p指向的内存地址处存储的整数值。
- p:表示指针p本身的值,即存储在p变量中的内存地址。指针变量存储的是一个内存地址值,用于指向其他变量或数据。对于指针变量p,p表示指针的值,也就是p所指向的内存地址。
要理解这两个概念的区别,可以将指针看作是一个存储地址的变量,而*p则是通过这个地址获取存储在该地址处的数据的方式。
int x = 10; // 定义一个整数变量x并初始化为10
int *p = &x; // 定义一个指向整数的指针p,指向变量x的地址
printf("%d\n", *p); // 打印p指向的内存地址处存储的整数值
printf("%p\n", p); // 打印指针p的值,即p指向的内存地址
在上述代码中,*p获取指针p所指向的内存地址处存储的整数值(10),而p获取指针p本身的值,也就是x变量的内存地址。
总结起来,*p用于访问指针所指向的内存地址处存储的值,而p用于获取指针本身的值,即存储的内存地址。
第二部分:i与&i
代码1:
int main(){
int i=100;
int *p;
p=i;
return 0;
}
代码2:
int main(){
int i =100;
int *p;
p=&i;
return 0;
}
代码1和代码2中的p=i
和p=&i
的区别主要是:
p=i
:将i的值赋给p所指向的内存空间,即p的值等于i的值。如果p之前没有分配内存空间,那么这个语句可能会导致未定义行为,因为p指向的内存空间是未知的。p=&i
:将i的地址赋给p,即p指向的内存空间为i的地址。这个语句确保了p指向了i所在的内存空间。
特殊说明:
在C语言中,p=&i
是最常用的指针赋值方式。它能够明确地将指针p指向变量i所在的内存空间,确保了指针的有效性。p=i
这种方式在实际应用中比较少见,因为它需要确保指针p已经分配了内存空间,并且这个内存空间的大小足够容纳变量i的值。如果未满足这些条件,这个语句可能会导致未定义行为。
第三部分:* ( * p+1)和 * ( * ( p )+1)
*(*p+1)
:首先, * p会获取指针p所指向的内存位置的值,然后在该值上加1,然后再使用*进行解引用操作,获取所得结果所指向内存位置的值。这种形式假设p是一个指向指针的指针。可以简单地将其理解为对指针进行单层解引用,然后再对解引用结果进行加1,即 * (*p+1)。
int x = 10;
int *p = &x;
int **q = &p;
int result = *(*q + 1); // 获取p指向位置的整数值,并对其加1
*(*(p)+1)
:首先,*(p)
会获取指针p所指向的内存位置的值,这个值是一个指针。然后,在该指针上加1,然后再使用*
进行解引用操作,获取所得结果所指向内存位置的值。
这种形式假设p是一个指向指针的指针。可以将其理解为对指针进行单层解引用,然后对解引用结果进行加1,再对加1后的指针进行解引用,即*(*(p)+1)
。
int x = 10;
int y = 20;
int *p = &x;
int *q = &y;
int *arr[] = {p, q}; // 指针数组,包含两个指针元素
int result = *(*(arr)+1); // 获取arr[0]指向位置的整数值,并对其加1
需要注意的是,对于*(*p+1)
和*(*(p)+1)
这样的指针操作,确保指针和指向的内存位置的有效性是非常重要的,以避免越界访问或意外行为。
*(*p+1)
和*(*(p)+1)
的区别在于操作符的优先级。虽然它们的区别对于大多数情况来说输出结果是相同的,但在某些特殊情况下,它们的输出结果可能会不同。
假设p
是一个指向整型数组的指针,指针p
指向了数组的首个元素。
-
*(*p+1)
:首先,*p
解引用指针p
,获取数组的首个元素的值。然后,在该值上加1,再次使用解引用操作,获取相对于首个元素之后一个位置的值。 -
*(*(p)+1)
:首先,*(p)
解引用指针p
,获取数组的首个元素的值,这个值是一个整型。然后,在该整型值上加1,再次使用解引用操作,获取相对于该整型值之后一个位置的值。
总结:
这两种表达式的输出结果通常是相同的,因为数组元素的连续存储使得它们在内存中是紧密排列的。所以在大多数情况下,*(*p+1)
和*(*(p)+1)
都会得到数组中的下一个元素。
然而,在以下两种情况下,它们的结果可能不同:
- 如果
p
指向最后一个数组元素,那么*(*p+1)
将引发未定义行为,因为超出了数组的范围。而*(*(p)+1)
将得到无效内存位置的值。 - 如果
p
是一个指向指针的指针,那么*(*p+1)
指的是指针所指向的内存位置上的指针值之后一个位置的值,而*(*(p)+1)
指的是指针指向位置的值之后一个位置的值。
综上,尽管大多数情况下,*(*p+1)
和*(*(p)+1)
的输出结果是相同的,但在某些特殊情况下,输出结果可能会有所不同。
说明:解引用操作的定义:
解引用操作是指通过指针获取指针所指向内存位置的值。在编程中,使用星号*
来表示解引用操作符。当对指针进行解引用操作时,实际上是在使用指针所指向的内存位置上的值。
通过解引用操作,可以访问和修改指针所指向内存位置的内容。如果指针指向的是一个变量,解引用操作将允许您读取或修改该变量的值。如果指针指向的是一个数组,解引用操作将允许您访问数组中的元素。同样,如果指针指向的是一个结构体或对象,解引用操作将允许您访问结构体或对象的成员。
在C和C++等语言中,对指针进行解引用操作的语法是将星号*
放在指针变量的前面。
例如,对于一个整型指针int *ptr
,可以通过*ptr
来进行解引用操作,从而获取指针所指向内存位置的整数值。
int x = 10;
int *ptr = &x; // ptr指向变量x
int value = *ptr; // 解引用操作获取指针ptr所指向位置的值,即x的值
需要注意的是,在对指针进行解引用操作之前,应确保指针是有效的,指向已分配的内存位置,以避免出现未定义的行为或错误。