这种方法是不被允许的,因为name是数组名,指向的仅仅是第一个数组元素的地址,而这个语句的意思是将字符串的首地址赋给name,这显然是不对的!
为与其对比: const char * sex; // 对指针分步初始化 sex = "girl"; // 这种初始化方法是可以的,因为sex为指针,当把字符"girl"赋值给sex时,表示把这个字符串的首地址赋给sex,这种是被允许的! 3,当初始化字符串数组时,需要明白的是: const char name[SIZE] = "Hello, my name is sheng."; // 其中的SIZE一定要比字符串所有的元素至少大1,因为至少要留一个位置给'\0',作为字符串的结尾 // 这样要时刻考虑数组的容量显得过于麻烦,所以通常情况下可以使用以下方法: char hobby[] = "My favorite sport is basketball."; // 让编译器计算数组大小的初始化数组,编译器会自动添加'\0'元素。 或者也可以用指针指向数组首地址的方法来初始化。 4,当用指针初始化字符串常量时,最好在其前面加const,表示其不会修改所指向的字符串常量,这样做更加安全。 const对指针的使用方法: a) const char *age = "eighteen."; // 表示指针age所指向的字符串是一个字符串常量,不能够被修改。而指针的内容可以被修改,即该指针还可以指向其他的字符串。 b) char * const age = "eighteen."; // 表示指针age只能指向这个字符串,不可再用于指向其他的char类型变量。 注意a类型实际上可以把非字符串常量也赋值给指针age,这是age就会把它当成一个字符串常量来对待,即不会修改它的值! 而b类指针仍可用于修改数据,所不同的是,他只能修改最初赋给它的值。 5,在观察string.h中的函数原型时,会发现其里面定义的函数原型除了极个别之外,函数的形式参量均为指针类型,表示当调用这些函数时,时刻要记得传给函数的实际参数也要为指针类型。 6,看下面这个例子: #include <stdio.h> #include <string.h> #include <ctype.h> #define ANSWER "SIMY" #define MAX 40 char * strupr(char *); int main(void) { char input[MAX]; // 声明一个已知容量的字符串数组,用以存放从键盘上键入的内容。 printf("Who is my lover?\n"); scanf("%s", input); strupr(input); while(strcmp(input, ANSWER)) { puts("You're wrong!"); scanf("%s", input); } puts("You're right!"); return 0; } char * toup(char * input) { while(*(input++)) { *input = toupper(*input); // 把小写转化成大写 } return input; } 1)注意当程序运行之前一定要为数组分配明确的大小,因为直到程序运行时才能读取键盘的内容,所以程序无法预先知道要为它留多大的空间! 2)这个程序我之前一直搞不懂,因为我以为从键盘读入的字符串是存在静态区的字符串常量,我之前一直以为这个函数改变了静态区的字符串常量,所以才会出现很多误区。但是当仔细分析之后发现: 我声明input数组的地方位于主函数,所以当toup()函数结束后input数组并不会被回收,但是由于声明的input为数组,所以从键盘键入的字符串实际上是以拷贝的方式存在数组中,所以改变这个数组的内容对原字符串没有影响! 而下面这个例子: #include <stdio.h> char *string(void) int main(void) { char *str=NULL; // 一定要初始化,好习惯 str=string(); printf("%s\n", str); return 0; } char *string(void) { char ptr[]="hello world!"; return ptr; } 这样做是无效的,因为函数中的ptr[]是一个在函数string中局部的数组,他被存在栈中,当这个函数被调用完毕之后,ptr[]的空间已经被回收,而返回的ptr指向的地址仍旧是ptr[] 存在时的地址,所以没有办法返回有效的地址,所以将无法输出ptr[]的内容! 而解决这个问题的办法,就是在这个数组初始化之前,在其前面添加static!