目录
常量字符串和数组创建的字符串
常量字符串
常量字符串和数组创建的字符串的区别
指针数组
数组指针
数组指针的作用
对于一维数组
对于二维数组
lucky同学在前面介绍了指针的一些基本内容,我们一起来回忆下:计算机将内存划分为一块一块的空间,且每一块有一个编号,这个编号就叫地址,即地址唯一标识一块空间,用来存放地址的变量叫做指针变量。指针类型与其所指向的数据有关,决定了指针解引用的时候能访问的权限。指针变量的大小也是固定的,32位平台下为4字节,64位平台下为8字节。还有指针的三种运算:指针加减整数、指针减指针、指针的关系运算。下面,lucky同学将进一步对指针进行介绍。
常量字符串和数组创建的字符串
对一个字符指针的修改和解引用:
#includeint main() { char ch = 'w'; char* pc=&ch; *pc='a'; printf("%cn",ch); // a return 0; }
常量字符串
一个常量字符串如 "abcdef( )" 的地址放到指针 p 里,指针存放的是这个常量字符串的首元素字符 'a' 的地址,打印时只需要知道首字符的地址就能找到整个字符串。注意的是,对于常量字符串,创建在常量区,是不能被随意修改的,所以可以在存储常量字符串地址的指针前面加上 const,防止被错误修改。
#includeint main() { char* p="abcdef"; // 常量字符串: a b c d e f //把这个字符串的首字符a的地址放到了指针p里 printf("%cn",*p); // a printf("%sn",p); // abcdef //打印这个字符串只需要给出这个字符串的首字符的地址 char* p="abcdef"; //常量字符串: a b c d e f *p='w'; //由于是常量字符串,*p不能改 printf("%sn",p); // err return 0; }
常量字符串和数组创建的字符串的区别
首先看下面一组代码:
#includeint main() { const char* p1="abcdef"; const char* p2="abcdef"; char arr1[]="abcdef"; char arr2[]="abcdef"; if(p1 == p2) { printf("p1 == p2n"); } else { printf("p1 != p2n"); } if(arr1 == arr2) { printf("arr1 == arr2n"); } else { printf("arr1 != arr2n"); } // 打印结果:p1 == p2 arr1 != arr2 return 0; }
分析两者的区别可以发现,由于常量字符串放在常量区,它的地址只会保存一份,所以对两个内容一样的常量字符串,分别放在两个指针里,那么这两个指针是相同的。
而对于由数组创建的字符串 char arr1[ ] = "abcdef" 和 char arr2[ ] = "abcdef" ,告诉我们初始化了两个数组,分别为数组 arr1 和数组 arr2 ,内存中这两个数组分别各为独立的空间,所以它们的首元素的地址也肯定是不同的。
注意:上面数组 arr1 和 arr2 是放在栈区的,p1、p2 是指针,也是放在栈区的,其指向的那个字符串是放在常量区的。常量字符串如果创建在常量区,永远不能被改,而数组创建的字符串就可以更改。
指针数组
指针数组,顾名思义,即存放指针的数组,如整型数组和字符数组的创建:
整形数组:
int arr[10]; //存放整形的数组字符数组:
char arr2[5]; //存放字符的数组
#includeint main() { int* p1=&a; int* p2=&b; int* p3=&c; // 数量多了会显得繁琐,借助指针数组 int* arr[3]={&a,&b,&c}; //arr就是一个指针数组 //打印 for(i=0;i<3;i++) { printf("%d ",*(arr[i])); } return 0; }
#includeint main() { int i=0; int j=0; int arr1[5]={1,2,3,4,5}; int arr2[5]={2,3,4,5,6}; int arr3[5]={3,4,5,6,7}; int* parr[3]={arr1,arr2,arr3}; // 分别存放三个数组首元素的地址 // parr是指针数组 for(i=0;i<3;i++) { for(j=0;j<5;j++) { //printf("%d ",parr[i][j]); printf("%d ",*(parr[i]+j)); // 也可以这样写 } printf("n"); } return 0; }
注意:
二维数组在内存中是连续存放的:
int arr[3][5]={{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
内存中:1 2 3 4 5 2 3 4 5 6 3 4 5 6 7
但上面代码中 parr 指针数组,虽然在打印的时候,有二维数组的影子,但其中的三组数据在内存中并不是连续存放的。
数组指针
与整形指针、字符指针分别指向整型和字符一样,数组指针即指向数组的指针,例如下面的p2:
int (*p2)[10];
p2是个指针,指向数组,这个数组有10个元素,每个元素是int,所以称p2是个数组指针
所以数组指针可以用来存放数组的地址:&数组名
通常情况下,我们说的数组名都是首元素的地址
但是有两个例外:
1、sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小
2、&数组名,这里的数组名表示整个数组,&数组名,取出的是整个数组的地
看下面代码,区分不同情况下的指针加一:
#includeint main() { int arr[10]={0}; int (*pa)[10]=&arr; // 利用数组指针一个数组的指针 printf("%pn",arr); // 首元素地址 0073FBEC printf("%pn",&arr[0]); // 首元素地址 0073FBEC printf("%pn",&arr); // 这个数组的地址 0073FBEC printf("%pn",arr+1); // 0073FBF0 整型指针加一跳过4个字节 printf("%pn",&arr[0]+1); // 0073FBF0 整型指针加一跳过4个字节 printf("%pn",&arr+1); // 0073FC14 数组指针加一,跳过这个数组的大小---40字节 return 0; }
数组指针的作用
对于一维数组
#include
void print1(int* arr,int sz)
{
int i=0;
for(i=0;i
可以知道,这个写法用来打印一维数组反而显得别扭,所以说数组指针一般不用于一维数组。
对于二维数组
#include
void print2(int arr[3][5],int c,int r)
{
int i=0;
int j=0;
for(i=0;i
注意理解:
arr[i] = *(arr+i)
arr[i][j] = *(arr+i)[j] = *(*(arr+i)+j)
#includevoid print1(int* arr,int sz) { int i=0; for(i=0;i 可以知道,这个写法用来打印一维数组反而显得别扭,所以说数组指针一般不用于一维数组。
对于二维数组
#includevoid print2(int arr[3][5],int c,int r) { int i=0; int j=0; for(i=0;i 注意理解:
arr[i] = *(arr+i)
arr[i][j] = *(arr+i)[j] = *(*(arr+i)+j)



