数组和指针

来源:互联网 发布:手机评测软件 编辑:程序博客网 时间: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++编程指南;

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 换手机号了淘宝账号怎么办 qq登录id密码忘记怎么办 iphone商店密码忘记了怎么办 淘宝账号被限制登入怎么办 手机换号码了qq登不上怎么办 换手机了qq登不上怎么办 微信帐号和密码错误怎么办 高考生忘记登录密码怎么办 高考生登录密码丢了怎么办 高考志愿登录密码忘了怎么办 电视声音和画面不同步怎么办 苹果5s不能开机怎么办 红米手机老是闪退怎么办 苹果7plus打字卡怎么办 手机总是出现无响应怎么办 手机淘宝怎么打不开了怎么办 淘宝买东西卖家不同意退货怎么办 苹果自带浏览器不能上网怎么办 淘宝账号买不了东西怎么办 支付宝被限制登录怎么办 微信登录不上 钱怎么办 淘宝账号买家权限被限制怎么办 淘宝中店新品打不开怎么办 旺旺号被限制有退款怎么办 登陆微信收不到验证码怎么办 淘宝店注册成功后怎么办 充电宝掉进水里怎么办 空光盘读不出来怎么办 苹果8plus丢了怎么办 苹果8plus掉了怎么办 淘宝账户被限制使用怎么办 飞利浦电脑显示器黑屏怎么办打开 微信忘记密码手机号停用怎么办 淘宝账号登录密码忘记了怎么办 淘宝支付密码输错了怎么办 淘宝支付密码忘记了怎么办 淘宝货品上架后显示过期怎么办 被淘宝客监控了怎么办 助学贷款支付宝账号忘记怎么办 离婚支付宝的钱怎么办 扫码加载不出来怎么办