字符数组和字符指针

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中的一个例子,完成将一个字符串中的所有大写字母全部转换为小写字母的功能:

[cpp]  view plain  copy
  1. View Code  
  2.  1 #include<iostream.h>  
  3.  2 #include<ctype.h>  
  4.  3   
  5.  4  /******************************************************************************/  
  6.  5 /* 
  7.  6  *    Convert a string to lower case 
  8.  7  */  
  9.  8   
  10.  9 int strlower(char *string)  
  11. 10 {  
  12. 11     if(string==NULL)  
  13. 12     {  
  14. 13         return -1;  
  15. 14     }  
  16. 15   
  17. 16     while(*string)  
  18. 17     {  
  19. 18         if(isupper(*string))  
  20. 19             *string=tolower(*string);  
  21. 20         string++;  
  22. 21     }  
  23. 22     *string='\0';  
  24. 23     return 0;  
  25. 24 }  
  26. 25 /*char *strlower(char *string) 
  27. 26 { 
  28. 27     char    *s; 
  29. 28  
  30. 29      
  31. 30  
  32. 31     if (string == NULL) { 
  33. 32         return NULL; 
  34. 33     } 
  35. 34  
  36. 35     s = string; 
  37. 36     while (*s) { 
  38. 37         if (isupper(*s)) { 
  39. 38             *s = (char) tolower(*s); 
  40. 39         } 
  41. 40         s++; 
  42. 41     } 
  43. 42     *s = '\0'; 
  44. 43     return string; 
  45. 44 } 
  46. 45 */  
  47. 46   
  48. 47 void main()  
  49. 48 {  
  50. 49     char *test="ABCDEFGhijklmN";  
  51. 50     strlower(test);  
  52. 51     cout<<test<<endl;  
  53. 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]。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值