C语言中由于指针的灵活性,导致指针能代替数组使用,或者混合使用,这些导致了许多指针和数组的迷惑,因此,刻意再次深入探究了指针和数组很有必要.
重新认知几个概念
数组:数组变量实际是指针变量.数组是多个元素的集合,在内存中分布在地址相连的单元中,所以可以通过其下标访问不同单元的元素。所以是在内存地址的概念讨论数组.但是,内存地址就是指针.哈哈,你大爷还是你大爷.
关于证明,详见文章https://mp.csdn.net/postedit/94859895中间动态数组部分.
指针:指针也是一种变量,只不过它的内存单元中保存的是一个标识其他位置的地址。由于地址也是整数,在32位平台下,指针默认为32位.关于其指向,就是指针变量所保存的地址单元中所存放的数据类型。
字符数组:不就是存字符的数组吗,地址连续.
#include <string.h>
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char** argv)
{
char str[10]="Amercian";
cout<<str<<endl;
char *p ;
p = str;//为什么可以把一个字符串赋给一个指针变量?
//其实真正的意义是 p="American" = 00000000006ffe30;首地址,地址连续,直到发现\0结束.
printf("%p\n",p);
printf("%s\n",p);
return 0;
}
%s可能的输出机制:
#include <string.h>
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char** argv)
{
char str[10]="Amercian";
char *s =str;
for(int i= 0; i < strlen(str) ; i++)
printf("%c\n", s[i]);
//while(*s!='\0')
//printf("%c",*s++);
return 0;
}
char * a[ ]
由于[ ] 的优先级高于* 所以a先和 [ ]结合,他还是一个数组,数组中的元素才是char * ,前面讲到char * 是一个变量,保存的地址。
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char** argv)
{
char* a [ ] = {"China","French","America","German"};
printf("%p %p %p %p\n",a[0],a[1],a[2],a[3]); //数组元素中保存的地址 ,即指针
printf("%p %p %p %p\n",&a[0],&a[1],&a[2],&a[3]);//数组元素单元本身的地址,即指针的指针
cout<<a[0]<<endl;
char** arg;
arg=a+2;
printf("%p\n",arg);
cout<<*arg<<endl;
return 0;
}
附:
二级指针保存的是一级指针的地址,它的类型是指针变量,而一级指针保存的是指向数据所在的内存单元的地址,虽然都是地址,但是类型是不一样.
**指向指针的指针
#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int p=1;//int型变量
int* a; //定义一个指向int型变量的指针
a=&p; //指针a存储了变量p的首地址
cout<<&p<<endl;
cout<<a<<endl; //打印首地址
cout<<*a<<endl;//打印在该地址上所存储的变量
int** arg;//定义一个指向int型变量的指针的指针
arg=&a; //指针arg存储了指向p的指针变量a的地址
cout<<**arg<<endl; //两次提领操作
return 0;
}
解释一下两次提领操作:因为指针变量a存储了int变量p的地址,所以第一次提领操作先根据a的地址找到获得a.(前提是,arg=&a);第二次相当于做了一次*a操作,显而易见.
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char** argv)
{
char* a [ ] = {"China","French","America","German"};
char** s;//char **为二级指针, s保存一级指针 char *的地址
s=a+0;
//printf("%p\n",arg);
printf("%s",*s);
printf("%s",a[0]);
printf("%s",*a);
return 0;
}
一个有趣的现象
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
cout<<**argv<<endl;
cout<<*argv<<endl;
cout<<argv<<endl;
cout<<argc<<endl;
return 0;
}