指针与数组的区别:
按照之前遍历数组的方法计算数组里存放的字符串个数
#include <stdio.h>
int main()
{
char str[] = " MARS CONCERT ";
int count = 0;
while (*str++ != '\0')
{
count++;
}
printf("总共有%d个字符!\n",count);
return 0;
}
结果发现报错,while循环里自增运算符必须运算在一个左值上。而数组名不是左值。C语言的lvalue是指用于识别或者定位一个存储位置的标识符,同时还必须是可修改的。但是数组名是不可以修改的,它是一个地址常量。
ar[i]和*(ar+1)这两个表达式都是等价的。无论ar是数组名还是指针变量,这两个表达式都没问题。但是,只有当ar是指针变量时,才能使用ar++这样的表达式。
所以我们增加一个指针target,用它来代替数组名,表示数组中第一个元素的地址。
#include <stdio.h>
int main()
{
char str[] = " MARS CONCERT ";
char *target = str;
int count = 0;
while (*target++ != '\0')
{
count++;
}
printf("总共有%d个字符!\n",count);
return 0;
}
*target++ != '\0' 其中++自增运算符优先级最高,但是它是下一次循坏才使用,第一次循坏还是使用target最初的值。取target地址里的值,判断是否为字符串结束符\0。不是,那么就进入第二次循环,从上一节课的学习知道,target+1是指针加1,递增它所指向类型的大小(以字节为单位),所以指向下一个字符的地址,取该地址里的字符,判断是否为字符串结束符\0....
指针数组与数组指针:
指向字符串指针
#include <stdio.h>
int main()
{
char *p1[4] = {
"大冰",
"你好",
"你坏",
"诗人",
};
int i;
for(i = 0; i<4; i++)
{
printf("%p\n",p1[i]);
//%s表示取出该地址的字符以及后面所有的字符
//使用%d时,表示取出这个字符串首字符的地址 (十进制)
//使用%p时,表示取出这个字符串首字符的地址(十六进制)
//p1[0]表示数组里第一个字符串首字符的地址
//p1[1]表示数组里第二个字符串首字符的地址
}
return 0;
}
之前学的指针是指向数组的第一个元素,而不是数组。
写成int str[5]={1,2,3,4,5}; int *p=str;的原因是数组名==数组第一个元素的地址==数组的地址。实际上它指向的是一个变量,而不是数组。
但是数组指针不同,它指向的是一个数组,所以
int str[5]={1,2,3,4,5}; int (*p)[5] = &str;
#include <stdio.h>
int main()
{
int str[5] = {1,2,3,4,5};
int (*p)[5] = &str;//p是指针变量,指向str这个数组的地址
//在数组里,str和&str的值是相同的
//但是str是将所有数组元素看成一个个不同的个体
//而&str是将整个数组作为一个整体
int i;
for (i = 0; i<5 ; i++)
{
printf("%d\n",*(*p + i));
//内部的*取得是数组,外部的*取得是数组元素
//p=&str; *p=str; *(*p)=str[0];
}
return 0;
}