1.计算字符串的大小
#include <stdio.h>
int function(char *p)
{
char* t = p;
while (*t++);
return t - p;
}
int main()
{
char a[] = "xcvbnm";
int k = function(a);
printf("%d", k);
return 0;
}
运行结果:7
程序分析:
在这个函数中,char *t = p;
使得 t
指向与 p
相同的位置。
然后通过 while(*t++)
,t
会一直递增,直到指向字符串结束的 '\0'
之后。
此时,t
所指向的位置与 p
所指向位置的差值,就是字符串所占用的内存单元个数(包括字符串结束的 '\0'
字符)。
所以在 return
语句中,返回 t - p
就能得到字符串占用的内存单元个数。
这为什么不是地址相减?
在 C 语言中,当对指针进行相减操作时,得到的结果是两个指针所指向的元素之间的元素个数,而不是地址的数值相减。
在这个函数中,p
和 t
是指向字符的指针,t - p
得到的就是从 p
开始到 t
所经过的字符个数,也就是字符串占用的内存单元个数(包括字符串结束的 '\0'
字符)。
所以,虽然是指针相减,但它反映的是字符元素个数的差值,而不是地址数值的简单相减。
2.初识二级指针
#include <stdio.h>
void f(int* s, int* t)
{
int* k;
if (*s < *t)
{
k = s;
s = t;
t = k;
}
}
int main()
{
int i = 3, j = 5;
int* p = &i;
int* q = &j;
printf("before:%d %d %d %d\n%p %p\n", i, j, *p, *q, p, q);
f(p, q);
printf(" after:%d %d %d %d\n%p %p", i, j, *p, *q, p, q);
return 0;
}
运行结果:
before:3 5 3 5
006FF8A8 006FF89C
after:3 5 3 5
006FF8A8 006FF89C
函数分析:
在 f
函数中,它试图交换两个指针所指向的值。但由于指针参数是值传递,所以在函数内部对指针的修改不会影响到函数外部指针的指向和它们所指向的值。
在 main
函数中,首先定义了两个整数 i = 3
,j = 5
,以及对应的指针 p
指向 i
,q
指向 j
。然后打印交换前的相关信息。
接着调用 f(p, q)
,但由于上述提到的参数传递机制,i
和 j
的值以及 p
和 q
的指向都不会改变。
最后再次打印相关信息,与交换前相比没有变化。
要在函数内部改变指针在函数外部的指向,需要传递指针的指针(即二级指针)。
#include <stdio.h>
// 改变指针指向的函数
void changePointer(int** ptr1, int** ptr2) {
int* temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}
int main() {
int a = 10, b = 20;
int* p = &a, * q = &b;
printf("Before: p = %p, q = %p\n", (void*)p, (void*)q);
changePointer(&p, &q);
printf(" After: p = %p, q = %p\n", (void*)p, (void*)q);
return 0;
}
运行结果:
Before: p = 004FFE98, q = 004FFE8C
After: p = 004FFE8C, q = 004FFE98