int a[ ] = {1, 2, 3, 4, 0}; //定义了一个数组,这个数组有5个元素,每个元素是一个 int 类型变量
这里的地址是相同的,是相同的意味着数组的地址和 0 号元素的地址是一样的
结论:
数值上相同但是意义上不同,一个是数组整体的地址,一个是元素个体的地址,虽然数值相同但是意义不同
除此之外类型也不同
int (*) [5]
(*) ------ 这里描述的肯定是一个指针类型
具体什么样的指针类型呐 ?指针类型有很多很多,这里的指针类型具体是哪一种呐?
看 int , [5] 这 2 个, 我们就清楚了,这个指针类型用于指向数组 指向什么样子的数组?
int [5], 由5个元素,每个元素是整型变量的数组
这个指针的名字为 pName
类型是 : int (*)[5];
&a 数组地址
用数组地址来初始化 pName
pa 这个指针 就指向了上面定义的数组a[ ]
int* p = a; 定义一个指针 p ,并且指向这个数组的第0 号元素
所以 &a 和 a 不同
在做赋值的时候,在做初始化的时候,类型必须一致,特别对于指针来说,如果类型不一致就不能相互的赋值
while 里面打印 p 指向的整型数
定义一个指向数组的指针
int (*pa) [5]; 这个数组长什么样子,由5个元素,每个元素是一个整型变量 ,这样一个指向数组的指针就定义好了
警告 : 赋值符号左右两边的指针类型不兼容
为什么打印 1,因为死循环了,当前p的值指向了数组当中的第 0 号元素,而第 0 号元素的值就为 1,所以这里反复不停的循环,反复不停的打印 1 出来,
while( *p ) 这里就是判断当前 p 所指向的元素值是不是 0 ,如果不是0,那么就继续的循环,如果是0呐,就跳出循环
p++ ; 移动指针的语句,将指针 p 指向下一个元素
为什么没有打印最后一个元素的值呐?
因为最后一个元素的值为0,当p++;指针移动到0的时候,while( *p )取到的值为0,既然取到的值为0,while 循环就跳出了
定义一个指针指向数组中的元素,比如说 p ,这个时候我们执行 p++;的操作,指针p 将会指向 4 ,
现在扩展成 p = p + i ,i 是任意一个整数值, 数组a 第 0 号元素的地址就是数组名 a,数组名可以看作一个指针,这个指针指向第0号元素,然后我们知道 a + 1 = > &a[ 1 ];(a + 1指的是第1号元素的地址)
使用 指针访问操作符 (*) 将得到的是第 i 号元素
然后定义了一个指针 p ,这个指针指向了第 0 号元素,换句话说在数值上 a 和 p 等价了,代表相同的地址值
意味着 我们可以定义一个指针,然后把这个指针指向数组中的第 0 号元素,之后就可以通过 p[ i ]这样的方式来访问数组元素了
#include <stdio.h>
int main()
{
int a[] = {1,2,3,4,5};
int* p = a;
int i = 0;
for(i= 0;i<5;i++)
{
printf("%d, %d\n", a[i], *(a + i)); // (a + i)就是数组中第 i 号元素的地址,对这个地址使用指针访问操作符的结果就是访问了地址中的元素,换句话说这里打印的结果就是 1 1,2 2,3 3,4 4,5 5
}
return 0;
}
又是一样的结果,意味着 : a[i] 和 p[i] 是等价的
#include <stdio.h>
int main()
{
int a[] = {1, 2, 3, 4, 5};
int* p = a;
int i = 0;
//对于一个数组来说有这样的等价关系
// a[i] <==> *(a + i) <==> *(p+i) <==> p[i]
for(i = 0; i < 5 ;i++)
{
printf("%d, %d\n", a[i], *(a + i));
}
for(i = 0; i < 5 ;i++)
{
printf("%d, %d\n", a[i], p[i]);
}
for(i = 0; i < 5 ;i++)
{
printf("%d, %d\n", p[i], *(p + i));
}
return 0;
}
p + i 得到的是什么呐?
也是一个地址值,第 i 号元素的地址值
a 的类型是int*
i 是 int 类型
然后做相加 a + i 最终的结果是内存地址 这个内存地址类型就是 int* 类型
& a 和 &p 打印出来的数值是一样的吗 ?
不一样,为什么不一样, a 是数组,所以&a 这样写,取到的是数组的起始地址 。 p 是变量,是一个指针变量,所以这样写 &p ,得到的是指针变量的地址,
注意 : 指针变量也是变量,既然是变量显然可以取到地址
所以 &a 和 &p 肯定不相等
数组的地址怎么可能等于另一个变量的地址呐?不可能
a 和 p 所对应的地址是相同的
对a 取地址,和对p 取地址 ,得到的结果不相同,为什么不相同?因为a 和 p是不同的程序元素,因此,他们有各自的,不同的地址
实验结果证明 : 数组名只是可以看作指针,而它并不是指针,数组名并不是指针
字符串的本质是 字符数组,一种特殊的字符数组,特殊在字符数组当中存在 0 元素,‘ \0 '
那么字符串常量又是什么呐?直接在程序中 用双引号所定义的字符序列 “ Delplin”
这是一个字符数组,这个字符数组因为有 0元素,所以成为了字符串
在 C 语言中要成功的被 %S 打印出来,那么是一个合法的 char* 类型
C 语言中的字符串,其类型为 char*
为什么打印出来的地址一模一样?
字符串常量本质是一个字符数组,那么它必然在内存中占空间,也就是说这个字符串常量是存在于内存中的,那么存在内存中具体哪个区呐? 全局数据区,并且起始于 *ps 地址处
当程序中需要使用 这个字符串常量时,简单的借助于 ps 指针就好了
因此在这段代码中,编译器其实这样做了,直接将这里的字符串常量 替换成了 PS 指针,事实上这里的 PS 指针并不存在,真正替换的目标就是 这里的地址,也就是这个字符串常量在全局数据区的起始地址,所以才会打印相同地址出来
打印相同的地址,这个地址就是 D.T Software 在全局数据区的起始地址
* : 指针访问操作符
++ : 自增运算操作符
先把指针所指向的内存中的值给拿出来,拿出来用于初始化变量 v ,完了之后p 指针进行指针移动
简单来说 2 件事 ,第一件事取值 ,第二件事移动
为什么是 1 和 2 呀?
*p++; 这里一次性干了2 件事
(*p)第一件事将 p 所指向的内存当中的值取出来,取到的值是 1 ,于是用 1 初始化 v
(p++) 第二件事 p++ ,指针移动,指向2
在 main 函数中首先定义了一个指针,这个指针被初始化为 空,也就是用 0 来进行初始化
D.T.Software 在程序中使用它的时候,其实就是使用它的起始地址,用 PS来指代它的起始地址,并且PS 它的类型是 char* ,换句话说 PS 的起始地址的类型就是 char*,于是这里等价于从指针中取值了,通过PS 取到的值就是字符 ' D '
s = "D.T.Software" 使用指针 s 来指向全局数据区当中的常量,于是就可以访问这个字符串常量当中的每一个字符了
怎么访问,一个while 循环来访问的 %c (每次打印的是一个字符), *s 先访问了 s 所指向的数据,这个时候 s 所指向的数据就是字符,然后进行移动,移动后指向下一个字符,所以这样不停的取值,不停的取值,不停的指向下一个字符,肯定 s 最终指向一个 '\0' 值,这个'\ 0' 值就是 D.T.Software这个字符串常量的结束符
打印结果
这个while ( *s )循环刚开始通过 s 取到的值为 0 吗?
不为 0 ,刚开始通过 s 取到的值是 D
打印 s 所指向的字符,然后移动s 指针,使其指向下一个字符
数组名可以看作一个指针,本质是不是指针,显然不是
&a 代表数组作为一个整体的地址
a 代表数组 0 号元素的地址 ,一个是整体的地址,一个是个体的地址,所以意义上不同
当指针指向数组元素时,才能使用组合拳 *p++;