- 指针与数值
通过指针我们可以访问内存中任意地址,那么自然可以访问数组,因为数组在内存中占据了一段连续的空间,那么如何实现的呢?
1 #include<stdio.h> 2 3 int main(){ 4 //定义一个整型数组 5 int array[4] = {7,15,3,9}; 6 //定义一个整型的指针 7 int *p; 8 //将数组的首元素地址赋值给指针p 9 p = &array[0]; 10 //打印出指针所指内存单元的值 11 printf("指针所指内存单元的值为%d\n",*p); 12 return 0; 13 }
运行结果:
代码的第9行是将数组的第0号位置的元素地址赋值给指针p,由于C中规定数组名代表数组首地址,也就是首元素的地址,所以第9行代码也可换成
p = array;
那么有些人就会疑问了,我要是想访问数组中其他元素呢?是不是还得定义另一个指针变量,让需要被访问的元素地址赋值给这个新的指针呢?答案是不需要
实际上从上面的p = array;代码中就能看出一些端倪,因为我们用array[2]时能直接访问数组的第2号元素,那么是不是可以用p[2]这种形式间接访问呢?
1 #include<stdio.h> 2 3 int main(){ 4 //定义一个整型数组 5 int array[4] = {7,15,3,9}; 6 //定义一个整型的指针并初始化 7 int *p = array; 8 //利用指针遍历整个数组 9 for (int i = 0; i < 4; i++) { 10 printf("第%d号元素为:%d\n",i, p[i]); 11 } 12 13 return 0; 14 }
运行结果为代码的第10行中p[i]等效于array[i],它也可以表达成*(p+ii)或者*(array+i)。下列代码就是演示这个效果
1 #include<stdio.h> 2 3 int main(){ 4 //定义一个整型数组 5 int array[4] = {7,15,3,9}; 6 //定义一个整型的指针并初始化 7 int *p = array; 8 9 printf("%d---%d---%d---%d\n", p[2], array[2], *(p+2), *(array+2)); 10 return 0; 11 }
程序代码的第9行中的*(p+2)的含义是将指针p移动8个字节(64为系统中int中用4个字节空间)然后取出接下来4个字节空间中的int数值,
*(array+2)的好意和*(p+2)的含义是一样如果指针变量是float型的那么*(p+2)的含义就是将指针p移动16字节,然后取出接下来8个字节空间的float数值
1 #include<stdio.h> 2 3 int main(){ 4 //定义一个整型数组 5 int array[4] = {7,15,3,9}; 6 //定义一个整型的指针并初始化 7 int *p = &(array+1); 8 9 printf("%d\n", *(p+2)); 10 return 0; 11 }
如果看明白了上述文字的叙述,那就不难猜出这个程序的输出结果,对,输出结果就是 9
- 指针与字符串
指针定义字符串
字符串是由多个字符组成的,我们可以用字符数组定义一个字符串有两种形式
1 //第一种定义方式,注意最后的'\0' 2 char country[] = {'C','h','i','n','a','\0'}; 3 //第二种定义方式,这种定义方式系统会在字符'a'的后面自动添加一个'\0' 4 char country[] = "China";
既然数组和指针有着很多的联系,我们自然会想到用指针指向字符串,进行一定的操作
1 char country[] = "China"; 2 3 char *p = country;
实际上我们可以省略字符数组这一步,直接用指针定义一个字符串
char *p = "China";
那么有人会问了,问什么数组不行呢?这是由于字符串的特殊之处,每个字符串结尾都有一个'\0'的结束标志,每当访问一个字符串时,遇到\0就会结束,而字符数组没有这个结束标志。
指针访问字符串
和字符数组输出字符串一样,我门只需要把需要输出的字符串首位置给出就行,其他的就交给编译器就行
1 #include<stdio.h> 2 3 int main(){ 4 5 char *p = "China"; 6 7 printf("%s\n", p); 8 return 0; 9 }
输出结果:如果将第7行代码 改为:
printf("%s\n", p+2);
那么输出结果就是,输出字符串不同于输出数组中的元素时要在指针前面加上指针运算符‘*’
使用注意:
- 字符串的以下两种初始化是不同的
1 char country[] = "China"; 2 3 char *p = "China";
代码的第一行称为字符串变量,它是放在内存中的栈区域,是可以修改的,例如
1 char country[] = "China"; 2 3 country[3] = 'P';
但是若果用指针定义的字符串我们称为字符串常量,它是放在内存中的常量区,是不可修改的例如:
1 //错误代码 2 char *p = "China"; 3 4 *(p + 2) = 'T';
一旦放在程序中运行,编译链接能通过,但是运行可执行文件的时候会崩溃
- 字符数组中我们是不可以使用以下方式定义字符串数组
//错误代码 char country[10]; country = "China";
但是指针能以相似的方式定义的
1 char *p; 2 3 p = "China";