1.字符数组初始化方式:
static char st[]={"C Language"};
不能写为:
char st[20];
st={"C Language"};
而只能对字符数组的各元素逐个赋值。
2. 对字符串指针方式
char *ps="C Language";
可以写为:
char *ps;
ps="C Language";
3.int main()
{
char str1[40]="hello world!"; //char *str1="hello world!";
str1[4]='A'; //若str1是指针型的,编译通过,但运行是此处会段错误
printf("%s\n",str1);
return 0;
}
4.
如果:int *p;
*p = 7;
则编译器(vs2008)会提示The variable 'p' is being used without being initialized.即使用了未初始化的变量p。
因为p是指向7所在的地址,*p = 7给p所指向的内存赋值,p没有赋值,所以p所指向的内存位置是随机的,没有初始化的。
int k;
int *p;
p = &k; //给p赋值
*p = 7; //给p所指向的内存赋值,即k= 7
5.字符串与指针的初始化和赋值
初始化:
char *cp = "abcdefg"; //这个初始化过程,是将指针cp指向字符串的首地址,而并不是传递字符串的值。因为,在C语言里面,没有整体处理一个字符串的机制
赋值:
cp = "abcdefg";
*cp=”abcdefg” ;//错误!字符串常量传递的是它的首地址,不可以通过*cp修改该字符串的值,因为该字符串为常量,而它只是简单的将指针指向该字符串常量
6.如果写出int *p = 0x12345678 ; 这条语句编译器会报错:'=' : cannot convert from ' const int ' to ' int * ' ,因为赋值操作符左边和右边的表达式的类型应该相同,而0x12345678是int型常量,p是一个指向int型的指针,两者类型不同,所以正确的方式是:int *p = (int *) 0x12345678 ;
7、将一个指针的地址赋给一个指针,如:int i = 3; int *ip = &i;int **pp = &ip;
在指针初始化的第5种方式中提到了用一个指针的地址来初始化一个指针。回忆一下上一讲的内容:指针是一种变量,它也有自己的地址,所以它本身也是可用指针指向的对象。我们可以将指针的地址存放在另一个指针中,如:
int i = 5000;
int *pi = &i;
int **ppi = π
此时的ppi即是一个指向指针的指针,下图表示了这些对象:
i的地址为108,pi的内容就是i的地址,而pi的地址为104,ppi的内容即是pi的地址。对ppi解引用照常会得到ppi所指的对象,所获得的对象是指向int型变量的指针pi。想要真正地访问到i.,必须对ppi进行两次解引用,如下面代码所示:
printf("%d", i );
printf("%d", *pi );
printf("%d", **ppi );
以上三条语句的输出均为5000。
下面是一个在vc6中的一个例子,完成将一个字符串中的所有大写字母全部转换为小写字母的功能:
- View Code
- 1 #include<iostream.h>
- 2 #include<ctype.h>
- 3
- 4 /******************************************************************************/
- 5 /*
- 6 * Convert a string to lower case
- 7 */
- 8
- 9 int strlower(char *string)
- 10 {
- 11 if(string==NULL)
- 12 {
- 13 return -1;
- 14 }
- 15
- 16 while(*string)
- 17 {
- 18 if(isupper(*string))
- 19 *string=tolower(*string);
- 20 string++;
- 21 }
- 22 *string='\0';
- 23 return 0;
- 24 }
- 25 /*char *strlower(char *string)
- 26 {
- 27 char *s;
- 28
- 29
- 30
- 31 if (string == NULL) {
- 32 return NULL;
- 33 }
- 34
- 35 s = string;
- 36 while (*s) {
- 37 if (isupper(*s)) {
- 38 *s = (char) tolower(*s);
- 39 }
- 40 s++;
- 41 }
- 42 *s = '\0';
- 43 return string;
- 44 }
- 45 */
- 46
- 47 void main()
- 48 {
- 49 char *test="ABCDEFGhijklmN";
- 50 strlower(test);
- 51 cout<<test<<endl;
- 52 }
其中,如果采用char *test=”ABCDEFGhijklmN”;会产生运行时错误。Char test[]=”ABCDEFGhijklmN”则程序正常运行,原因如前所述。
---------------------------------------------------------------------------------------------------------------------------------
2016.4.12
a与&a的区别
#include<stdio.h>
void main( void )
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
return;
}
输出结果:2,5。
*(a+1)其实很简单就是指a[1],输出为2.
问题关键就在于第二个点,*(ptr-1)输出为多少?
解释如下,&a+1不是首地址+1,系统会认为加了一个整个a数组,偏移了整个数组a的大小(也就是5个int的大小)。所以int *ptr=(int *)(&a+1);其实ptr实际是&(a[5]),也就是a+5.
原因为何呢?
&a是数组指针,其类型为int(*)[5];
而指针加1要根据指针类型加上一定的值,不同类型的指针+1之后增加的大小不同,a是长度为5的int数组指针,所以要加5*sizeof(int),所以ptr实际是a[5],但是ptr与(&a+1)类型是不一样的,这点非常重要,所以ptr-1只会减去sizeof(int*),a,&a的地址是一样的,但意思就不一样了,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5]。