1. 字符指针与字符串
C语言通过使用字符数组来处理字符串
通常,我们把char数据类型的指针变量称为字符指针变量。字符指针变量与字符数组有着密切关系,它也被用来处理字符串
初始化字符指针是把内存中字符串的首地址赋予指针,并不是把该字符串复制到指针中char str[] = "Hello World";char *p = str;
在C编程中,当一个字符指针指向一个字符串常量时,不能修改指针指向的对象的值char *p = "xiaoqiang";*p = 'h'; //错误,字符串常量不能被修改
/*案例1:通过创建两个字符数组,再用指针去控制其中一个数组的首字母,从而证明字符数组存的相同字符串是局部变量,存储在俩个独立的空间中 demo1*/
#include <stdio.h>
#include <ctype.h>
int main(int argc,char *argv[])
{char ch1[] = "xiaoqiang";char ch2[] = "xiaoqiang";
char *p;p = ch1;
if(isalpha(*p)){if(isupper(*p))*p = tolower(*p);else*p = toupper(*p);}printf("%p %s\n", p, p);
p = ch2;printf("%p %s\n", p, p);return 0;
}
/*运行结果:
linux@ubuntu:~/C/day07$ gcc demo1.c -Wall
linux@ubuntu:~/C/day07$ ./a.out
0xbfe73e38 Xiaoqiang
0xbfe73e42 xiaoqiang
*/
/*案例2:通过创建两个相同的字符串常量,查看相同字符串常量的地址 demo2*/
#include <stdio.h>
#include <ctype.h>
int main(int argc,char *argv[])
{char *p1 = "xiaoqiang";char *p2 = "xiaoqiang";
printf("&p1=%p p1=%p p1=%s\n",&p1, p1, p1); //&p1=0xbf959d28 p1=0x8048520 p1=xiaoqiang
printf("&p2=%p p2=%p p2=%s\n",&p2, p2, p2); //&p2=0xbf959d2c p2=0x8048520 p2=xiaoqiang//俩字符指针变量地址不同,证明是俩个指针变量,指向的地址都相同,即字符串常量在静态存储区域,位于同一地址,所指结果也是相同的。字符串常量不可修改,但指针变量可以指向另外的地址。return 0;
}
/*测试结果:
linux@ubuntu:~/C/day07$ gcc demo2.c -Wall
linux@ubuntu:~/C/day07$ ./a.out
&p1=0xbf959d28 p1=0x8048520 p1=xiaoqiang
&p2=0xbf959d2c p2=0x8048520 p2=xiaoqiang
*/
/*案例3:在不使用任何函数的情况下实现俩个字符串的拼接 demo3*/
#include <stdio.h>
int main(int argc,char *argv[])
{char ch[100] = "xiaoqiang";char * q = " like xiaotian",* p;
p = q;
int i = 0;printf("ch:%s\n",ch);printf("q:%s\n",q);
while(ch[i] != '\0')i++;
while(*p != '\0'){*(ch+i) = *p;i++;p++;}
*(ch+i) = *p;
printf("ch+q,ch:%s\n",ch);printf("ch+q,q:%s\n",q);
return 0;
}
/*打印结果:
linux@ubuntu:~/C/day07$ gcc demo3.c -Wall
linux@ubuntu:~/C/day07$ ./a.out
ch:xiaoqiang
q: like xiaotian
ch+q,ch:xiaoqiang like xiaotian
ch+q,q: like xiaotian
*/
2. 指针数组
所谓指针数组是指由若干个具有相同存储类型和数据类型的指针变量构成的集合(即存储指针的数组或叫存储地址的数组),指针数组的一般说明形式:<存储类型> <数据类型> *<指针数组名>[<大小>];指针数组名表示该指针数组的起始地址
/*案例:利用指针数组存放二维数组的每个一维数组地址,要求输出二维数组,并求出二维数组所有元素的和*/
#include <stdio.h>
int main(int argc,char *argv[])
{int * p[3];int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};int i,j, sum;
p[0] = a[0];p[1] = a[1];p[2] = a[2];sum = 0;
for(i = 0;i < 3;i++){for(j = 0;j < 4;j++){ printf("%d ",*(p[i]+j));sum += *(p[i]+j);}puts("");}printf("sum=%d\n",sum);
return 0;
}
/*测试结果:
linux@ubuntu:~/C/day07$ gcc demo4.c -Wall
linux@ubuntu:~/C/day07$ ./a.out
1 2 3 4
5 6 7 8
9 10 11 12
sum=78
*/
3. 多级指针
把一个指向指针变量的指针变量,称为多级指针变量
对于指向处理数据的指针变量称为一级指针变量,简称一级指针变量,简称一级指针
而把指向一级指针变量的指针变量称为二级指针变量,简称二级指针
二级指针变量的说明形式如下<存储类型> <数据类型> **<指针名>;
多级指针运算指针变量加1,是向地址大的方向移动一个目标数据。类似的道理,多级指针运算也是以其目标变量为单位进行偏移。比如,int **p;p+1移动一个int *变量所占的内存空间。再比如int **p,p+1移动一个int **所占的内存空间
多级指针和指针数组指针数组也可以用另外一个指针来处理
/*案例:用二级指针打印字符串*/
#include <stdio.h>
int main(int argc,char *argv[])
{char *ps[5] = {"New York city","Beijing city","Moscow city","London city","Paris city"};char **pps;int i;
pps = ps;
for(i = 0;i < 5;i++)printf("%s\n",*(pps+i));
return 0;
}
/*运行结果:
linux@ubuntu:~/C/day07$ gcc demo5.c -Wall
linux@ubuntu:~/C/day07$ ./a.out
New York city
Beijing city
Moscow city
London city
Paris city
*/
4. void指针和const
4.1 void指针
void指针是一种不确定数据裂隙的指针变量,它可以通过强制类型转换让该变量指向任何数据类型的变量
一般形式为:void * <指针变量名称>
对于void指针,在没有强制类型转换之前,不能进行任何指针的算术运算
作用:可以将更多种类的数据类型用一个指针去解决
/*案例测试:将俩个不同的数据类型 用同一个指针进行输出*/
#include <stdio.h>
int main(int argc,char *argv[])
{int m = 10;double n = 3.14;void * p;
p = &m; //p = (void *)&m;printf("p = %d\n",*(int *)p);
p = &n;printf("p = %f\n",*(double *)p);
return 0;
}
/*运行结果:
linux@ubuntu:~/C/day07$ gcc demo6.c -Wall
linux@ubuntu:~/C/day07$ ./a.out
p = 10
p = 3.140000
*/
/*案例2:使用void的指针遍历一维数组*/
#include <stdio.h>
int main(int argc,char *argv[])
{int a[] = {1,2,3,4,5,6,7,8,9};int i,n;void * p;p = a;n = sizeof(a)/sizeof(a[0]);for(i = 0;i < n;i++)printf("%d ",*((int *)p + i));puts("");return 0;
}
/*运行结果:
linux@ubuntu:~/C/day07$ gcc demo7.c -Wall
linux@ubuntu:~/C/day07$ ./a.out
1 2 3 4 5 6 7 8 9
*/
4.2 const变量
作用:常量化变量的值
一般形式如下:conts <数据类型> 变量名 = [<表达式>];
常量化变量是为了使得变量的值不能改变
const修饰指针,常量化指针目标表达式
一般说明形式如下:const <数据类型> * <指针变量名称>[=<指针运算表达式>]
常量化指针目标是限制通过指针改变其目标的数值,但<指针变量>存储的地址值可以修改,只是不能修改这个地址所指向的值
常量化指针变量
一般说明形式如下:<数据类型> *const <指针变量名称>[= <指针运算表达式>]
使得<指针变量>存储的地址不能改变。但可以通过*<指针变量名称>修改指针所指向的值
const修饰谁,谁就不能修改