一切伟大的行动和思想,都有一个微不足道的开始。
hello world.
目录
字符指针
字符指针是指向字符型数据的指针变量。我们知道c语言中有整型,浮点型,字符型但没有字符串型,我们通常用字符数组来存储字符串。
另外,C语言还支持用一个指针指向字符串的方式来表示字符串。
注意,这样赋值时,“abcdef”为常量字符串,"abcdef"代表的是常量,不是把abcdef放到指针里,其实是把首字符a的地址赋给p,我们来验证一下
首先,我们先说一下双引号的作用 :
1.申请了空间(在常量区),存放了字符串
2. 在字符串尾加上了'/0'
3.返回地址
为什么可以将字符串常量赋值给字符指针变量?
因为定义的是一个普通字符指针,并没有定义空间来存放"abc",所以编译器得帮我们找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器最合适的选择。"abcdef"的值不是字符本身,而是返回的地址,是地址就可以用指针来接收。所以可以将字串常量赋值给字符指针变量。
注意,用字符数组存储字符串的时候,"abcdef"不是常量字符串,定义了一个字符数组就定义了空间存放字符串,字符数组是将字符逐个存放,所以编译器
就将char [] = "abcdef" 解析为char[]={'a',b'','c','d','e','f','\0'};
因为“abcdef”为常量字符串,所以无法修改其值,如下,程序崩溃。
我们最好是用const修饰一下,程序就不会出错了
做个题练下手~
输出什么呢?
解析:创建数组是需要开辟空间的,不同的数组就要开辟不同的空间,所以arr1和arr2所在的内存空间是不同的,数组名是首元素地址,空间不同,地址不同,所以arr1 !=arr2;而“abcdef”是常量字符串,存储在常量区,不可修改,地址固定,是首字符a的地址,所以p1==p2.
指针数组
指针数组是数组,是存放地址的数组。
[ ]的优先级比*高,所以parr先与[ ]结合,表示数组,数组元素为指针。
类比分析:
指针数组的应用:
小试牛刀~
数组指针
什么是数组指针呢?相同道理,首先,它是个指针。指向的是数组。
指向数组的指针为数组指针。
类比分析:
int *p=NULL;//p是整形指针--指向整形的指针--可以存放整形的地址
char* pc=NULL;//p是字符指针--指向字符的指针--可以存放字符的地址
char (*p)[10];//p是数组指针--指向数组的指针--可以存放数组的地址
数组指针的应用
这里需要注意,&arr取出的是整个数组的地址,即p指针是arr的地址,即p==&arr;&arr和数组名arr意义不同。*p 解引用操作使其拿到这个数组,即*p==arr,arr为数组名(首元素地址)
这样太别扭太麻烦我们平常不这么用,数组指针用于二维数组以上才高效。
让我们看一下
数组传参有两种形式:
第一种:
第二种:
我们来分析一下第二种传参的形式:
二维数组数组名为首元素地址;但是二维数组的首元素地址是什么呢?
当我们说数组名是首元素地址时,我们需要把二维数组想象为一维数组,第一行为第一个元素,第二行第二个元素,第一行又是一个一维数组,数组有五个元素,每个元素是int,二维数组数组名为首元素地址即第一行的地址,是一个一维数组的地址,所以传参时我们可以用数组指针接收。
我们来分析一下三个打印:
打一波题~
最后一个解析:
数组参数、指针参数
在写代码的时候我们需要把数组或者指针传给函数,那函数的参数该如何设计呢?
数组传参:
一维数组传参:
二维数组传参:
指针传参
一级指针传参
思考:
当一个函数的参数部分为一级指针的时候,函数能接受什么参数?
void test1(int* p) //test1函数能接受什么参数?
{}
void test2(char* p) //test1函数能接受什么参数?
{}
答案:1.指针 2.变量地址
二级指针传参:
思考:
当一个函数的参数部分为二级指针的时候,函数能接受什么参数?
1.一级指针的地址
2.二级指针
3.指针数组