`
godfrey90
  • 浏览: 54897 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

c语言中 *和[]的讨论

    博客分类:
  • c++
阅读更多
1.声明定义与内存分配
1.1一个由c/C++编译的程序占用的内存分为以下几个部分
(1)栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。
(2)堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
(3)全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
(4)文字常量区—常量字符串就是放在这里的。程序结束后由系统释放。
(5)程序代码区

1.2
通过*声明的话是将指针存放在栈区域,具体指针指向的值可以在常量区,全局区或者堆上。
通过[]声明的话是将整个数组存放在栈区域,并且声明变量指向自身,即数组的第一个元素。

看一个一维数组的例子
#include <iostream>
using namespace std;

main()
{
     char *c1 = "abc";
     char c2[] = "abc";
     char *c3 = ( char* )malloc(3);
     //    *c3 = "abc" //error
     strcpy(c3,"abc");
     c3[0] = 'g';
     printf("%d %d %s\n",&c1,c1,c1);
     printf("%d %d %s\n",&c2,c2,c2);
     printf("%d %d %s\n",&c3,c3,c3);
     getchar();
}   

运行结果
2293628 4199056 abc
2293624 2293624 abc
2293620 4012976 abc

1.3如果用[]方式声明变量的话可以用{}来定义,比如char a[]={'a'.'b','c','d'},但是用*声明的则不可以。因为这种方式是数组的独特定义方式。

2.二位数组
以上是一维数组的例子,我们再来看看二维数组

2.1[][]声明
可以把这样声明的一个二维数组看作一个一维数组来看。数组的所有元素全部在栈区。
(1)首先,不可以用char a[][]或者char a[3][]声明数组,报错为array type has incomplete element type 即,第二维的数组的类型不明确。

(2)可以这样声明 char a[][3],但是声明的时候必须要为其赋初值,这样编译器才知道要为该数组在栈中分配多大的空间。
如下例:
#include <stdio.h>
int main()
{
	char x[][2]={'1','2','3','4'};
	printf("%c",*((char*)x));
	printf("%c",*((char*)x+1));
	printf("%c",*((char*)x+2));
	printf("%c",*((char*)x+3));
}

运行结果为1234

(3)可以这样声明 char a[3][3],这个是最标准的二位数组声明,二位数组可以当作一维数组,通过指针来取值,如上例。

2.2[]*组合声明
(1)char *a[],这样的声明代表a是一个数组,数组每个元素是一个指针。如果[]中没有具体值的话,就需要赋初值,和char a[][3]的情况是一样的。因为char a[][3]代表一个数组,数组中每个元素都是一个长度为3的数组。

(2)char (*a)[],这样的声明代表a是一个指针,指向一个数组,这里的[]可以没有具体值,但是这样的情况栈中只存放一个指针,其他所有值在堆中。

2.3**声明
char **a 就是一个指向指针单元的指针,栈中只存放一个指针。

3.函数传值
在函数传值的时候,如果是要传一个二维数组的话,在函数的形参声明中最好的方式是char (*a)[3],如果用char **a进行形参声明的话会出现错误,因为形参数组无法识别第一维的大小,必须要在形参中声明第一维的大小。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics