笔记------指针与数组
2012-03-08 16:16
232 查看
以下的知识点总结于《c陷阱与缺陷》
1.指针与数组
c语言中的数组值得注意的地方有以下两点:
(1).c语言中只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来。
(2).对于一个数组,我们只能够做两件事:确定该数组的大小,以及获得指向该数组下标为0的元素的指针。其它有关数组的操作,哪怕它们咋看上去是以数组下标进行运算的,实际上都是通过指针进行的。换句话说,任何一个数组下标运算都等同于一个对应的指针运算。
现在考虑下面的例子:
下面我们再看
这个语句是非法的。因为calendar是一个二维数组,即“数组的数组“,在此处的上下文中使用calendar名称会将其转换为一个指向数组的指针;而p是一个整型变量的指针,这个语句试图将一种类型的指针赋值给另一种类型的指针,所以是非法的。
很显然,我们需要一种声明指向数组的指针的方法。
这个语句的实际效果是,声明了*ap是一个拥有31个整型元素的数组,因此ap就是一个指向这样的数组的指针。因而,我们可以这样写:
这样,monthp将指向数组calendar的第一个元素,也就是数组calendar的12个有着31个元素的数组类型元素之一。
2.非数组的指针
假定我们有两个这样的字符串s和t,我们希望将这两个字符串连接成单个字符串r。要做到这一点,我们可以借助常用的函数库strcpy和strcat。下面的方法似乎一目了然,可是却不能满足我们的目标:
之所以不行的原因在于不能确定r指向何处。我们还应该看到,不仅要让r指向一个地址,而且r所指向的地址处还应该有内存空间可供容纳字符串,这个内存空间应该是以某种方式已经被分配了的。
我们再试一次,记住给r分配一定的内存空间:
只要s和t指向的字符串并不是太大,那么现在我们所用的方法就能够正常工作。不幸的是,c语言强制要求我们必须声明数组大小为一个常量,因此我们不能够确保r足够大。然而,大多数c语言实现为我们提供了一个库函数malloc,该函数接受一个整数,分配能够容纳同样数目的字符的一块内存。大多数C语言实现还提供了一个库函数strlen,该函数返回一个字符串中所包括的字符数。
有了这两个库函数,似乎我们就能够像下面这样操作了:
第一个原因,malloc函数有可能无法提供请求的内存。
第二个原因,给r分配的内存在使用完之后应该及时释放,这一点务必要记住。
第三个原因,也是最重要的原因,就是前面的例程在调用malloc函数时并未分配足够的内存。我们必须为r多分配一个字符的空间。
做到了这些,并且注意检查了函数malloc是否调用成功,我们就得到正确的结果:
3. 作为参数的数组声明
在c语言中,我们没有办法可以将一个数组作为函数参数直接传递。
如果我们使用数组名作为参数,那么数组会立刻被转化为指向该数组第1个元素的指针。
c语言中会自动地将作为参数的数组声明转化为相应的指针声明。
也就是说,像这样的写法:
1.指针与数组
c语言中的数组值得注意的地方有以下两点:
(1).c语言中只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来。
(2).对于一个数组,我们只能够做两件事:确定该数组的大小,以及获得指向该数组下标为0的元素的指针。其它有关数组的操作,哪怕它们咋看上去是以数组下标进行运算的,实际上都是通过指针进行的。换句话说,任何一个数组下标运算都等同于一个对应的指针运算。
现在考虑下面的例子:
int calendar[12][31];这个语句声明了calendar是一个数组,该数组拥有12个数组类型的元素,其中每个元素都是一个拥有31个整型元素的数组(而不是一个拥有31个数组类型的元素的数组,其中每个元素又是一个拥有12个整型元素的数组)。
下面我们再看
int *p; p = calendar;
这个语句是非法的。因为calendar是一个二维数组,即“数组的数组“,在此处的上下文中使用calendar名称会将其转换为一个指向数组的指针;而p是一个整型变量的指针,这个语句试图将一种类型的指针赋值给另一种类型的指针,所以是非法的。
很显然,我们需要一种声明指向数组的指针的方法。
int (*ap)[31];
这个语句的实际效果是,声明了*ap是一个拥有31个整型元素的数组,因此ap就是一个指向这样的数组的指针。因而,我们可以这样写:
int calendar[12][31]; int (*monthp)[31]; monthp = calendar;
这样,monthp将指向数组calendar的第一个元素,也就是数组calendar的12个有着31个元素的数组类型元素之一。
2.非数组的指针
假定我们有两个这样的字符串s和t,我们希望将这两个字符串连接成单个字符串r。要做到这一点,我们可以借助常用的函数库strcpy和strcat。下面的方法似乎一目了然,可是却不能满足我们的目标:
char *r; strcpy(r,s); strcat(r,t);
之所以不行的原因在于不能确定r指向何处。我们还应该看到,不仅要让r指向一个地址,而且r所指向的地址处还应该有内存空间可供容纳字符串,这个内存空间应该是以某种方式已经被分配了的。
我们再试一次,记住给r分配一定的内存空间:
char r[100]; strcpy(r,s); strcat(r,t);
只要s和t指向的字符串并不是太大,那么现在我们所用的方法就能够正常工作。不幸的是,c语言强制要求我们必须声明数组大小为一个常量,因此我们不能够确保r足够大。然而,大多数c语言实现为我们提供了一个库函数malloc,该函数接受一个整数,分配能够容纳同样数目的字符的一块内存。大多数C语言实现还提供了一个库函数strlen,该函数返回一个字符串中所包括的字符数。
有了这两个库函数,似乎我们就能够像下面这样操作了:
char *r,*malloc(); r = malloc(strlen(s) + strlen(t)); strcpy(r,s); strcat(r,t);这个例子还是错的,原因有三。
第一个原因,malloc函数有可能无法提供请求的内存。
第二个原因,给r分配的内存在使用完之后应该及时释放,这一点务必要记住。
第三个原因,也是最重要的原因,就是前面的例程在调用malloc函数时并未分配足够的内存。我们必须为r多分配一个字符的空间。
做到了这些,并且注意检查了函数malloc是否调用成功,我们就得到正确的结果:
char *r,*malloc(); r = malloc(strlen(s)+strlen(t)+1); if(!r){ complain();//错误处理 exit(1); } strcpy(r,s); strcat(r,t); /*一段时间之后在使用*/ free(r);
3. 作为参数的数组声明
在c语言中,我们没有办法可以将一个数组作为函数参数直接传递。
如果我们使用数组名作为参数,那么数组会立刻被转化为指向该数组第1个元素的指针。
c语言中会自动地将作为参数的数组声明转化为相应的指针声明。
也就是说,像这样的写法:
int strlen( char s[]) { /* 具体内容*/ }与下面的写法完全相同:
int strlen(char *s) { /*具体内容*/ }
相关文章推荐
- 【c语言学习笔记】指针数组和数组指针以及在做题的时候遇到的问题
- C/C++学习笔记四(指针、数组)
- 黑马程序员----C 语言学习笔记之数组指针与字符串指针
- C语言笔记6--指针与数组
- 郝斌老师C语言学习笔记----指针和数组
- 算法学习笔记之四:巧妙运用指针解决链表、字符串、数组等问题(同向双指针VS对向双指针)
- 关于数组和指针的相应基础笔记整理
- FreeBASIC学习笔记——8.3 指针与数组
- 指针数组 学习笔记
- C/C++数组名与指针区别深入探索(转自刘志强的笔记)
- C++学习笔记2--函数重载 复杂的数据 内存对齐 指针数组 结构与指针 传值传址传引用 联合枚举类型别名
- 【C Prime Plus】学习笔记,Chapter 10,数组和指针之五
- 《C语言深度剖析》笔记 之 指针与数组
- c++学习笔记(六):数组指针
- C++ 学习笔记(四)(数组和指针)
- C语言学习笔记(17) 数组和指针分析
- <深入理解C指针>学习笔记和总结 第四章 指针和数组
- C语言学习笔记21——多维数组和多维指针
- 笔记4:指针和数组、函数结合分析
- 黑马程序员--C语言自学笔记---11数组、指针、推箱子小游戏