讲他们之间的关系之前先了解下面几个名词的概念,通过实例分析他们之间到底存在什么联系
数组指针:
指向数组元素的指针
数组指针的作用:
使用数组指针间接访问数组的元素
数组指针的定义:
int *p;
数组指针的初始化:
int a[4]={1,2,3,4};
int *p = a; //数组指针,定义了一个指针变量p赋值数组的首地址(第一个元素的地址),p指向数组的第一个元素
int *p = &a[0]; //等价上面一句话
数组指针如何访问数组的元素:
1)p+1 表示指向数组的下一个元素
2)p-1 指向数组的上一个元素
总结:
对于一个一维数组来说
int a[5];
1)获取 a[i]的地址有几种方法?
(1)&a[i]
(2)a+i
(3) int *p = a;
p+i
2) 获取 a[i]的值有几种方法?
(1)a[i]
(2)*(a+i)
(3) int *p = a;
*(p+i)
(4)*(&a[i])
应用:逆序数组:
void nixuArray(int a[],int len){
//定义数组指针
int *p = a;
//定义下标
int i = 0,j = len-1;
int temp;
while (i
指针数组:
存放指针的数组,就是指针数组
指针数组的定义:
数据类型 * 数组名[数组长度];
int *pa[3];
//定义了一个指针数组,数组名是pa,可以用来存放3个指针(必须是int类型变量的指针)
指针数组的使用:
int a=3,b=4,c=5;
int *pa[3]={&a,&b,&c};
//打印的是指针数组的第一个元素得值
printf(" &a = %p\n",&a);
printf(" pa[0] = %p\n",pa[0]);
//打印指针数组的首地址
printf(" pa = %p\n",pa);
printf(" &pa[0]= %p\n",&pa[0]);
//访问a的值 a = 3
printf(" *(&a) = %d\n",*(&a));
printf(" *(pa[0]) = %d\n",*(pa[0]));
//使用数组名来访问 a的值
//*pa == pa[0] (a的地址)
//**pa
printf("%d\n",**pa);
int a1[2][2]={1,2,3,4};
//定义了一个指针数组 ,赋值为a1[0] 是第一行的地址
int *pa1[2]={a1[0],a1[1]};
printf("**pa1 = %d\n",**pa1);
//pa1+1 &pa1[1]
//*(pa1+1) pa1[1]
printf("**(pa1+1) = %d\n",**(pa1+1));
两个指针变量之间的运算
1)两个指针之间的减法运算
(1)0x0006 - 0x0003 = 3 (意义不大)
(2)常见的用法:两个指针都指向同一个数组
i.判断两个指针变量指向的元素是否连续
ii.判断两个指针变量之间相隔几个元素
int a[5]={1,2,3,4,5};
int *p = a; //p指向了数组的第一个元素
int *p1 = &a[3]; //p指向了数组的第四个元素
注意:两个指针变量之间没有加法运算
如果两个指针变量指向同一个元素 那么他们相减的结果是 0
判断两个指针变量指向的元素是否相邻(连续),他们相减的结果是 1的绝对值
//2、两个指针变量之间的关系运算
// p1 > p //使用大于或者小于来比较的 不是相减;
//1 表示p1在高位(这里就是p1>p)
//0 p在高位或者他们指向了同一个位置(这里可能是p1<p或者是p1=p)
printf("p1 > p = %d\n",p1 > p);
数组名访问二维数组之指针在二维数组中的应用;
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
//列指针
//a[0] == &[0][0] a[0]+1==&a[0][1] a[0]+2==&a[0][2]
printf("&a[0][1] = %p\n",&a[0][1]);
printf("a[0]+1 = %p\n",a[0]+1);
printf("*(a[0]+1) = %d\n",*(a[0]+1)); //3
printf("&a[0][2] = %p\n",&a[0][2]);
printf("a[0]+2 = %p\n",a[0]+2);
//行指针 a[0] a[1] a[2]
//a+1 //第二行的首地址
//a+2 //第三行的首地址
printf("a[1] = %p\n",a[1]);
printf("a+1 = %p\n",a+1);
printf("a[2] = %p\n",a[2]);
printf("a+2 = %p\n",a+2);
// a+1 第二行第一个元素的地址
//*(a+1) == &a[1][0]
printf("*(a+1) = %p\n",*(a+1));
printf("&a[1][0] = %p\n",&a[1][0]);
//a[i]+j 获取的 &a[i][j]
//*(a[i]+j) 获取 a[i][j]
//a[i] *(a+i)
//*(*(a+i)+j); -----> a[i][j]
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
//a[i] *(a+i)
//printf("%d\t",*(a[i]+j));
printf("%d\t",*(*(a+i)+j));
}
printf("\n");
}
数组指针:
定义一个指针变量,让这个指针变量指向一维数组的元素
二维数组指针
行指针,用来指向二维数组的每一行,存放的是行的首地址
定义格式: 数据类型 (*行指针变量名)[数组第二维的长度];
二维数组指针的初始化
int a[2][3];
int b[2][2];
float f1[4][4];
//假设我要定义一个指向数组a的一个行指针
// a = &a[0] = &a[0][0] = a[0]
int (*p)[3] = a;
二维数组指针的使用
*(*(p+i)+j) //就是获取二维数组的每个元素
实际操作:
int main(int argc, const char * argv[]) {
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
//二维数组指针
//二维数组指针可以替代数组名去使用
int (*p)[4] = a;
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
//遍历数组
printf("%d\t",*(*(p+i)+j));
}
printf("\n");
}
return 0;
}
指针数组喝二维数组指针的区别:
1.int *p[3]={&a,&b,&c};pa是一个指针数组;
2.int (*p)[3];这是一个二维数组指针;
前者表示一个指针数组,有三个下标变量p[0],p[1],p[2];
后者表示一个纸箱二维数组的指针变量。表示长度为3的一维数组或者说它的烈说为3;
字符串指针:
定义: char *字符串指针变量名 = "字符串内容";
用作:用来保存一个字符串
实际操作如下:
#include
#include
#include
int main(int argc, const char * argv[]) {
//"zfbanzhang zaiyiqi" 这个字符串存储在常量去
//str 只保存了字符串常量的首地址
char *str = "zfbanzhang zaiyiqi";
//指针变量都是占用8个字节
printf("sizeof(str) = %ld\n",sizeof(str));
printf("str len = %ld\n",strlen(str));
//str是指针变量
//str重新指向另外一个字符串常量 "I LOVE YOU"
//保存的是 "I LOVE YOU" 字符串常量的首地址
str = "I LOVE YOU";
printf("%s\n",str);
char ch[]="abc"; //存在栈区
ch[2]='Z';
printf("%s\n",ch);
//读取字符串常量的某个字符
printf("%c\n",*(str+2)); //L
for (int i=0; i
%s\n",str3);
return 0;
}
一维字符数组
char ch[10]={'a','b'};
char ch1[]="abc";
二维字符数组
char ch2[3][10]={{'a','b'},{'b'},{'c'}};
用二维数组来保存多个字符串
//用二维的字符数组可以存储多个字符串
//第一维存的是每个字符串的首地址
//每个字符串的长度,不能超过第二维长度
char ch3[3][5]={"abc","def","kkkk"}
a b c \0 \0
d e f \0 \0
k k k k \0
ch[1][3] = 'Z';
实例操作如下:
#include
int main(int argc, const char * argv[]) {
char ch3[3][5]={"abc","def","kkkk"};
//存放的是一个二维数组
ch3[1][3] = ‘Z’;//将第二行第四列的值改为z 也成为赋值;
for (int i=0; i<3; i++) {
printf("%s\n",ch3[i]);
}
return 0;
}
char型指针数组和字符数组区别:
//char 类型的指针数组
char *name[3]={"abcdasfadsfasdfasdfasdf","def","kkk"};
for (int i=0; i<3; i++) {
//name[i]
printf("%s\n",*(name+i));//这里打印的值可以直接谢伟name[i];
}
字符串指针和字符数组的区别
//字符串指针:
char *ss = "abc";
//指向可以改变
//ss是一个指针变量
ss = "helloWorld!";
//字符数组:
char s1[]="abc";
//s1是数组名,是一个常量,不能被赋值,是不能改变的;
//s1 = "helloworld!";
字符串排序应用:
#include
#include
/**
* 实现字符串的排序
*
* @param arr <#arr description#>
* @param len <#len description#>
*/
void sortString(char *arr[],int len){
//冒泡排序
//临时存放地址
char *temp;
for (int i=0; i
0) {
//实现arr[j] arr[j+1]交换
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
int main(int argc, const char * argv[]) {
//输入5个国名并按字母顺序排列后输出。
char *name[]={ "CHINA","AMERICA","AUSTRALIA","FRANCE","GERMAN"};
for (int i=0; i<5; i++) {
printf("%s\n",name[i]);
}
//字符串排序
sortString(name, 5);
printf("\n\n");
for (int i=0; i<5; i++) {
printf("%s\n",name[i]);
}
return 0;
}