数组和指针
来源:互联网 发布:手机评测软件 编辑:程序博客网 时间:2024/06/05 10:33
在C语言中,数组在作为参数传递时都转换为指向数组起始地址的指针,非数组形式的数据实参均以传值形式调用。C语言允许程序员把形参声明为数组或者指针,编译器知道何时形参是作为数组声明的,但事实上在函数内部,编译器始终把它当做一个指向数组第一个元素的指针。这样,编译器可以产生正确的代码,并不需要对数组和指针这两种情况作仔细区分:
void func1(char p[]);void func2(char* p);
以上两种形式的函数在处理一个字符数组时,在函数内部的处理是一致的。
当处于函数内部时,没有一种容易的方法分辨传入的不同实参。在函数内部对数组参数的任何引用都将产生一个对指针的引用。而处于函数外部时,函数并不自动知道指针所指的数组共有多少个元素,所以必须要有个约定,如数组以NUL结尾或者另有一个附加的参数表示数组的范围。(这一点与一个字符在串末尾加‘\0’表示结束类似):
void fun1(char ca[]){printf("char ca:\n");printf("sizeof ca:%d\n", sizeof(ca));int main(){char ga[] = "goodbye";fun1(ga);printf("ga:\n");printf("sizeof ga:%d\n", sizeof(ga));system("pause");return 0;}
可以看到,在函数内部想通过sizeof得到数组的长度是不正确的,这是因为传入函数内部的数组被转化为了一个指向char*的指针,所以sizeof(ca)的长度就是一个指针的长度,在32位的环境下是4个字节。而在main函数中的sizeof(ga)返回了数组的真实长度8。
定义指针时,编译器并不为指针所指向的对象分配空间,它只是分配指针本身的空间,除非在定义时同时赋给指针一个字符串常量进行初始化:
char* p = "goodbye";
只有对字符串常量才是如此,如果对其他类型的常量分配空间,如:
int* p = 3;以上代码编译不过。
与此同时,初始化指针时所创建的字符串常量被定义为只读,如果试图通过指针修改这个字符串的值,程序会出现未定义的行为。
数组也可以用字符串常量进行初始化:
char a[] = "goodmorning";
与指针不同的地方在于,由字符串常量初始化的数组是可以修改的。其中的单个字符是可以改变的,如:
strncpy(&ga[4], "night!!", 7);
数组的值被改变为“goodnight!!”。
下面有一个小程序来加深对数组参数的地址和数组参数的第一个元素地址的理解:
void fun1(char ca[]){printf("char ca:\n");printf("%x\n", &ca);printf("%x\n", &(ca[0]));printf("%x\n", &(ca[1]));}void fun2(char* pa){printf("char* pa:\n");printf("%x\n", &pa);printf("%x\n", &(pa[0]));printf("%x\n", &(pa[1]));printf("%x\n", ++pa);}int main(){char ga[] = "goodbye";fun1(ga);fun2(ga);printf("ga:\n");printf("%x\n", &ga);printf("%x\n", &(ga[0]));printf("%x\n", &(ga[1]));system("pause");return 0;}
看了上述的运行结果,发现数组参数的地址和数组参数的第一个元素的地址竟然不一样,这是为什么呢?
这是因为在fun1()的第二行,打印的内容为”&ca“,而&ca的实际意义为ca的地址,即指向ca的指针。在函数内部,ca本身就是一个指向数组第一个元素的指针,无需取ca的地址,直接打印ca的值即可,取得ca的地址反而弄巧成拙。将第二行的语句替换为:
printf("%x\n", ca);
即可获得与数组第一个元素相同的地址。看完上面的文字,可以去做林锐博士的《高质量C_C++编程指南》后面的第二题测试一下。
参考资料:
1.C专家编程(Expert C Programming);
2.高质量C_C++编程指南;
- 指针和指针数组
- 指针数组和数组指针
- 指针数组和数组指针
- 指针数组和数组指针
- 指针数组和数组指针
- 数组指针和指针数组
- 指针数组和数组指针
- 数组指针和指针数组
- 指针数组和数组指针
- 指针数组和数组指针
- 数组指针和指针数组
- 指针数组和数组指针
- 指针数组和数组指针
- 数组指针和指针数组
- 数组指针和指针数组
- 指针数组和数组指针
- 指针数组和数组指针
- 数组指针和指针数组
- App开发和发布过程中证书基础知识讲解
- zoj 1450 Minimal Circle【最小覆盖圆问题】
- 不能接收彩信的原因及自动收发彩信解决方案
- 浅析GLib
- Keil uVision中的Logic Analyzer(逻辑分析仪)简单使用
- 数组和指针
- 对笔记本中EC的理解
- iOS开发之检测网络连接状态
- 遍历一次链表,将元素反过来
- javascript函数的调用
- cocos2d-x学习资源汇总
- GLIB 链接和简介
- C++用ShellExecute打开IE
- 求代数和(struts2框架)