回 帖 发 新 帖 刷新版面

主题:一个怪程序

    这是一个在别人的书里摘下的程序,它的结果有些怪。不知道有没有人知道哪里怪和怎么怪??

char ga[]="abcdefghijklmn";
void my_array_func(char ca[10]){
    printf(" addr of array param = %#x \n",&ca);
    printf(" addr (ca[0]) = %#x \n",&(ca[0]));
    printf(" addr (ca[1]) = %#x \n",&(ca[1]));
    printf(" ++ca = %#x \n\n",++ca);
}
void my_pointer_fun(char *pa){
    printf(" addr of ptr param = %#x \n",&pa);
    printf(" addr (pa[0]) = %#x \n",&(pa[0]));
    printf(" addr (pa[1]) = %#x \n",&(pa[1]));
    printf(" ++pa = %#x \n\n",++pa);
}

main(){
    printf(" addr of global array = %#x \n",&ga);
    printf(" addr (ga[0]) = %#x \n",&(ga[0]));
    printf(" addr (ga[1]) = %#x \n",&(ga[1]));
    my_array_func(ga);
    my_pointer_fun(ga);
}

以上是程序,如果有人知道的话,麻烦告诉我。先谢了。

回复列表 (共18个回复)

11 楼

    对于13和14楼的程序,相信大家都可以知道,a是"等于"&a的。但是,我想问一下,既然a是一个指针,代表的是一个地址,而取a的地址,居然是a指向的地址。
    这是什么意思呢??难道说,a既保存了数组的首地址,又保存了a自己的地址吗?
    我还是那句,这是一个未定义行为,由编译器决定怎么做。

12 楼

  
   
int  a[]; a的值和&a是相同的.

但是两个值要分别赋给不同类型的指针.

13 楼

我想是不是可以这样理解a(a是数组名)与&a与&a[0]三者:
  a:是数组名在程序中代表数组的首地址;
  &a:这里是取数组a的地址并不是取a本身的地址;
  &a[0]:这是取数组第一元素a[0]的地址;
这三者所代表的或取德的都是同一地址。
             
         这问题搞的我晕晕的!

14 楼

但是
char a[]="abkjsdfj";

void fn(char ca[])

{
    printf(" addr of array ca = %#x \n",ca);/*  ca指实参a(数组a的首地址),即ca=&a[0]=a; */
    printf(" addr of array &ca = %#x \n",&ca);/*  此处&ca指新创建的指针变量ca的地址值.  ca!=&ca   */
    printf(" addr (ca[0]) = %#x \n",&(ca[0]));
    printf(" addr (ca[1]) = %#x \n",&(ca[1]));
    printf(" ++ca = %#x \n\n",++ca);
}

void main()
{
printf(" addr of array a[] = %#x \n",a);
printf(" addr of array &a = %#x \n",&a);
fn(a);


}

addr of array a[] = 0x422a30
addr of array &a = 0x422a30
addr of array ca = 0x422a30
addr of array &ca = 0x12ff30
addr (ca[0]) = 0x422a30
addr (ca[1]) = 0x422a31
++ca = 0x422a31

15 楼

To denisity:
    在你的程序里,我想你要说的问题应该是函数fn()里ca!=&ca的问题吧。
    K&R的名著中说到,作为函数定义的形式参数,char s[]和char* s是一样的。
    不过,这只用于函数定义的形式参数!
    也就是说,无论你在fn()中用的是char ca[]还是char *ca,编译成可执行代码时,都是一样的。这时的char ca[]中的ca是一个变量,而不是一个常量!因为它和char* ca相同。以下程序完全可以执行:
#include "stdio.h"
char p[]="abcdefgh";



void print(char tp[]){
    while((*tp)!='\0'){
        printf("%c",*tp);
        tp++;
    }
}

int main(void){
    print(p);
    return 0;
}
注意,在你的程序中的全局数组中的a是一个常量,a++不合法。
    在实参a传值给形式参数cp时,要有一个值保存cp。所以cp!=&cp。这部分内容看meteor135的话,那里有很清楚的说明。但你的a又是“等于”&a的。这是作为形参和原来的数组的不同。
    谢谢大家对这个帖子的关心,不过这个帖子现在也未免太长了吧……能不能……
    

16 楼

看了楼主的贴我已经将自已那些不确定和错误贴子删掉,我又查了些资料和做了些实验,为了叙述方便我将楼主的问题重新进行了定义,现将自已的结果贴出了给大家交流:
1、关于a和&a的区别
#include <stdio.h>

int main(void)
{
    int a[20];
    int *p1; //声明一个指向整型变量的指针变量p1
    int (*p2)[20];//声明一个指向数组的指针变量p2
    p1 = a;//p1指向数组a的第0个元素
    p2 = &a;//p2指向一个有20个元素的数组a
    printf("a = %d\n",sizeof(*p1));//p1所指向的类型为一个整型变量输出为:4
    printf("&a = %d\n",sizeof(*p2));//p2所指向的类型为一个有80个元素整型数组为:80
    printf("&a = %d\n",sizeof(*(&a));//&a指向数组的指针,和上边那条语句一样说明其为指向一个有20个元素的数组,输出为80
    getchar();
    return 0;
}

如果让p1 = &a是非法的,因为p1是指向整型变量的指针,而&a是一个数组类型的指针,它们不是同一类型所以不能互相赋值。为什么一些早期编译器(tc2.0)能编译成功,是因为早期的编译器没有数组指针的这个概念,所以可以顺利赋值。现在的编译器(bc6++,dev c++4.0)这样赋值是编译不过去的,它们会提示类型不匹配。
结论:数组名a是一个指向数组元素的指针,它指向第0个数组元素,&a是一个指向整个数组的指针。

2、关于数组类型在函数形参中的声名
当数组在函数中作为形参定义时,C语言把作为形参的数组定义转换为指针定义,举个列子:
int function(char *s)
{
  .......
}

int function(char s[])
{
  ......
}

这两个定义函数的方法是一样的.

17 楼

To 好好学习:
    打7楼开始都是在回答你的问题,你说你想给谁评分?    

18 楼

还是楼主评分吧,我的问题也是由你们的帖子才想到的。
    等我以后做楼主时在给你们评分! 嘿嘿!

我来回复

您尚未登录,请登录后再回复。点此登录或注册