任何时候都可以使用数组,使用指针。
成都创新互联是一家专注于成都网站建设、网站设计与策划设计,应城网站建设哪家好?成都创新互联做网站,专注于网站建设十年,网设计领域的专业建站公司;建站业务涵盖:应城等地区。应城做网站价格咨询:028-86922220
定义时,通常只有字符指针,和字符数组指针直接定义。用来表示字符串或字符串数组。
其他一般定义数组。操作时用指针或数组。
其他指针,多半用在参数传递,数据结构内部(不确定需要内存的大小,或者链表,二叉树等链式结构)的时候。
还有一种是有些函数参数就是指针,这时定义一个指针,来操作传进来的指针参数比较好。
指针作为参数,有一下几种用法,
1)当作数组用,用来获取或设置数组元素。
2)把一个比较长的数据结构传入函数,只需要一个指针就够了。
3)传入变量的地址,用来读取或修改变量的值,主要是为了修改用。
直接定义一个不指向任何对象的指针,并且也从不给他赋值,没什么意义;
指针要么指向数组,要么指向变量,要么动态申请内存。
NULL指针,只是一个方便的指针,表示不指向任何对象。
真正有用的还是指向具体对象的指针。
如果定义了一个指针,使用时要让他指向一个具体对象,当需要他不指向什么对象的时候,给他赋值为NULL;
PS:
C语言,数组名只是一个指针常量而已,离开定义可见处,数组大小的信息就不存在了。
只有定义完全可见的地方,才可以获得数组的大小。
数组作为函数的参数,和外部引用声明都不能获得数组的大小。
参数只能传递指针,参数的大小只是指针的大小;
只能看到声明的地方,获取数组大小的努力,只能换来错误。
void fun1(int a[10]) //== void fun1(int a[]) ==void fun1(int *a)
{
}
void fun2(int [10][10])// ==void fun2(int a[][10])== void fun2(int (*a)[10])
{
}
指针数组:数组成员是指针的数组。
作用:数组的属性全有。因为成员是指针,这就可以延伸出很多内容。包括:
成员是函数指针,整个数组就是一类相关函数的集合,便于代码架构的管理。
成员是链表指针啦,char指针,这种就是能做出类似散列表的结构。
总体来讲,就是一组相关数据的指针的集合,达到的目的就是搜集指向相关数据的指针放到一个集合里面。
同意楼上!
不能定义*d[0],因为这个数组的大小为0!
可以这样来
#include stdio.h
#include stdlib.h
#include string.h
int main()
{
char *d[4];
d[0]=malloc(1*sizeof(char));
strcpy(d[0],"web");
printf("%s",d[0]);
return 0;
}
此时*d[]为一个指向指针的指针
d[0]=malloc(1*sizeof(char));
此句话的意思是,分配1个字节的内存空间给d[0],也就意味着d这个数组的第一个元素[0]内保存的是一个1字节空间的地址,因为d[0]指向一个地址!
你可以这样理解
对于普通的数组(例如 char d[4];),在内存中是这样的
变量:内存地址:内容
d[0]:0x400000h:'w'
d[1]:0x400001h:'e'
d[2]:0x400002h:'b'
d[3]:0x400003h:'\0'
而在此处 char *d[4]; *d[0] = malloc(1*sizeof(char));,是这样的'
d[0]:0x400000h:0x400100h
d[1]:0x400001h:0x400101h
d[2]:0x400002h:0x400102h
d[3]:0x400003h:0x400103h
而在内存0x400100h处
才保存着"web\0"
不好意思,我上面说错了,应该是
d[0]:0x400000h:0x400100h
d[1]:0x400001h:NULL
d[2]:0x400002h:NULL
d[3]:0x400003h:NULL
而在内存0x400100h处
0x400100h:'w'
0x400101h:'e'
0x400102h:'b'
0x400103h:'\0'
对应的,你的代码执行后,内存变量应该是这样的
d[0]:0x400000h:0x400100h
d[1]:0x400001h:0x400104h
d[2]:0x400002h:0x400108h
d[3]:0x400003h:NULL
在内存0x400100处:
0x400100h:'w'
0x400101h:'e'
0x400102h:'b'
0x400103h:'\0'
0x400104h:随机字符
......
0x400108h:随机字符
以上内存地址是以字节方式内存对齐的,用一些编译器编译后可能地址会有些问题(比如d[0]到d[1]不止差了4,可能是8),但总体框架就是这样!
int **a可以表达一个二维数组。为什么呢?
你可以这么理解 * p[3]表达的是一个数组指针,这个指针 p[0]表示的是数组存的第一个地址。而数组实际上是一串连续地址的块。每一个小块存着一个内容。每次访问数组时,你为什么可以用数组名+下标访问呢? //比如a[i];
实际上就是 访问*a+i; * 这个符号可以表示你存的是变量的地址。而数组地址的第一位为int类型变量存的地址(你可以直接使用数组的地址加上单位变量的空间的大小去访问下个元素)。在这个程序中int *p[3] 表示可以存三个int 类型的地址。而p正好把二维数组的三个一维数组的开头的int类型变量的地址给存起来了。
给你举个例子
我现在输出的是地址,是不是连续的?
用*运算符获取地址的内容。
实际上p[i]与 *(p+i)是表达的是同一个意思。只不过只有数组可以定义一个连续的空间
(数组的第一个地址是随机的其他的是连续的。)单独用指针的话会随机分配的
数组的指针可以存三个地址。当然可以访问二维数组了。