引例:
char str[8]=”heng”;
char *pt; pt=”is clever”;
char *pt1=”goodJob”;
字符数组的数组名str作为一个变量,在栈定义.对字符数组初始化时,等价于对连续的内存初始化.str[8]={‘h’,’e’,’n’,’g’,’\0’,’\0’,’\0’,’\0’};
但是对于字符指针而言,pt是定义在栈中的变量(永远是4字节),只是这个变量指向的是存在静态区的字符串数组,所以在此,”is clever”是存在静态区10字节的常量,它是没办法改变的.但是可以改变指针pt所指,比如pt=pt1,此时就指向了字符串常量”goodJob”;
即:
在定义一个字符数组时,编译时即已分配内存单元,有确定的地址。而定义一个字符指针变量时,给指针变量分配内存单元,但该指针变量具体指向哪个字符串,并不知道,即指针变量存放的地址不确定。
说明:
字符串函数strcpy(字符数组,字符串);
则在程序中,可以使用如下语句:
strcpy(str,”love”);
strcpy(str,pt);
但不能使用
strcpy(pt,”love”);
一些总结:
1.字符串”hihi”是否为常量分为两种情况:
char str[]=”hihi”则不是常量;
char *pt=”hihi”则是常量; 类似于const char *pt;
2,数组类型与数组元素的类型和大小共同决定的,比如char a[3]和a[4]
就是不一个类型.
3.指针名是一个变量,数组名是一个常量,所以
str++;错
pt++;对
4.
char p[]; // 编译不过
char p[0]; // sizeof(p) = 0
char p[8]; // sizeof(p) = 8
char * p = malloc (10); // sizeof(p) = 4
用运算符sizeof可以计算出数组的容量(字节数),但是计算不出指针指向空间的容量,只能计算出指针变量的空间容量(4字节)
指针就是指针,成不了数组
4.对于函数参数列表中的数组类型编译器会将其理解为对应类型的指针.
(1)void fun(int a[100],char str[100],char *p)
a和str都可以等同于*int,*char.
所以sizeof(a)==sizeof(str)==sizeof(p)==4
(2)void func(char a[100]) {
printf(“%d “,sizeof(a)); //4字节而不是100字节 说明函数的数组参数都是看做指针
}
在C语言中,我们没有办法可以将一个数组作为函数参数直接传递。如果我们使用数组名作为参数,那么数组名会立即被转换为指向该数组第1个元素的指针.因此,将数组作为函数参数毫无意义。所以,C语言中会自动地将作为参数的数组声明转换为相应的指针声明。
5.char *pt=”is clever”;//注意p指向常量字符串
*pt=’#’;//编译器不能发现该错误,运行时错误
*好了,终于可以来点实际的题目了,学习完后品尝哈:
void fun(char *p)
{
printf(“%p\n”,p);
}
void changeValue(char *p)
{
*(p+1)=’!’;
puts(p);
}
int main()
{
char str[]=”meng”;
char *pt=”is clever”;
const char *pt1=”and handsome”;
const char *pt2=”and handsome”;
// *pt=’#’;//运行会出错.
fun(str);
fun(pt);
fun(pt1);
fun(pt2);
changeValue(str);
//changeValue(pt);//字符串为常量,所以不能进行改变.运行出错
return 0;
}