昨天的随笔里忘记提的重要一点:
指针指向的地址是有长度的,但是指针就是个针,一个针只有一个针尖,只能指向一个地址。
当我们用这种方式测量指针长度时
char *pstring;
printf("%d\n", sizeof(*pstring));
实际上我们测的不是指针占据的内存大小,而是指针指向的数据占据的内存大小,哪怕为空。由于代码中是char型,所以输出结果为1。
当我们测量却忘记带 * 号时,如:
printf("%d\n", sizeof(pstring));
这就是系统指针的大小了,如果你是32位的编辑器,那地址总线宽度是4 bytes,你得到的结果就是4 如果你是64位的编辑器,那地址总线宽度是8 bytes,你得到的结果就是8
指针进阶:
访问一个字符串 有两种方式
第一种:使用字符数组存放一个字符串,字符数组是变量的集合,可以通过对字符数组的元素进行修改而实现对字符串的修改。
例子:char string[] = "Hello world!"; 就是一个一维数组,里面有12个字符。可以通过替换指定位置的值而修改字符串的值。
第二种:定义字符指针,令其指向一个字符串的地址而非字符数组。此时由于指针指向常量,指针只能调用不能修改。
例子:char *string = "Hello world!"; 即为指向常量的字符指针。一般不这么用。
使用指针访问字符数组:
1. 定义一个字符指针并将其初始化为空
例子:char *pstring = NULL;
或者将其初始化为指向字符数组
例子:char string[] = "Happy New Year!";
char *pstring = string;
2. 使用指针指向存放字符串的字符数组,方法如下:
#include <stdio.h>
int main()
{
char string[] = "Happy New Year!"; //定义一维数组
char *pstring = NULL; //定义指针并将其初始化为空
pstring = string; //指针指向数组地址,这里涉及一个知识点。数组是变量的集合,因此可以简单地使用数组的名字进行表示数组地址,而不用取地址符&。
//或者如果不用取地址符不舒服的话,也可以这么用:
//pstring = &string[0]; 这么麻烦,何必呢。
printf("%s\n", pstring); //打印字符指针所指地址的值
return 0;
}
3. 通过指针来复制字符串
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "Happy New Year!", str2[20], *p1, *p2;
p1 = str1;
p2 = str2;
while(*p1 != ‘\0‘) //将指针p1指向的数据,除终止符 ‘\0‘ 外,复制到指针p2中
{
*p2 = *p1;
p1++;
p2++;
}
printf("%d\n\n", strlen(str2)); //输出为19,而非15,数组str2的字符串后面缺少终止符,因指针p2未将终止符一起复制
*p2 = ‘\0‘; //此时指针p2指向str2的字符串后面一位,为str2的字符串末尾添加终止符
puts (str2); //正常输出Happy New Year!
printf("\n%d\n", strlen(str2)); //测得结果为15,str1中的字符串通过两个指针完整复制到字符串str2
return 0;
} //书上原题
如果使用sizeof 测试字符串长度,结果都是20。这是定义时数组的长度,而非数组中的字符串对应的长度。具体sizeof和strlen的区别,读者可以去网上搜索,很多大佬讲得很细了。我就不赘述了。
4. 多维字符数组与指针数组,例子如下:
#include <stdio.h>
int main()
{
int i;
char string[4][10] =
{
"China",
"Japan",
"Canada",
"America",
}; //定义完多维字符数组
for (i = 0; i < 4; i++)
printf("%s\n", string[i]); //打印多维字符数组
char *pstring[4]; //定义指针数组
for (i = 0; i < 4; i++)
pstring[i] = string[i]; //对指针数组赋初值
for (i = 0; i < 4; i++)
printf("%s\n", pstring[i]); //打印指针数组
return 0;
}
我在网上搜了一下,可能很少会用到指针数组,这个,由于经验太少,我不清楚。
5. 关于昨天的指针入门,我从书上看到个例子,对指针的理解有些帮助。如下:
#include <stdio.h>
void change(int * a, int * b)
{
int t;
t = *a;
*a = *b;
*b = t;
}
int main()
{
int a = 3, b = 5;
change(&a, &b);
printf("%d, %d\n", a, b);
return 0;
}
这里书上的题目定义了交换的函数,如果change函数不用指针来写的话,你在编译器里敲一下就知道了,交换失败。
书上没说为啥,我琢磨着函数调用之后,交换的值的地址是系统分配给change函数的内存地址,函数用完就会销毁。交换了的值不会返回。
如果你照我说的敲了,可能在change里面打印一下就会换了,但是在main里面没换,因为地址上的值没有被处理,传递到change函数的是值而不是地址,地址的值没变,那自然也就不会交换了。
加油,希望明天能看链表。
原文地址:https://www.cnblogs.com/life-long-learner-xly/p/12222858.html