user-0 提问: 关于C语言指针的一些疑问。

回复:
user: user-1
content: 引用 楼主 a491057947 的回复:疑问1：定义一个字符数组 char var[]={'a','b','c'}，这里的数组名为该数组的首地址。当执行printf("%s",var)时可输出全部字符a,b,c，为什么打印首地址可以输出所有字符？  疑问2：定义一个字符指针数组 char *var2[]={"aaa","bbb","ccc"}，表示一个一维数组内存放着三个指针变量，他们指向的内容分别为“aaa”,"bbb","ccc"（这个是C program language 中讲的），所以*var2[0]应该为指针var2[0]所指向的内容，为“aaa”，但测试结果却是"a"(在字符数组中，*var与var[0]的输出一样都为”a“)为什么？疑问1： char var[]={'a','b','c','\0'};用%s输出时需要在字符串结尾加一个'\0'结束标志，你那样写会在abc之后有乱码 疑问2： 表示一个一维指针数组内存放着三个指针变量 *var2[0]应该为指针var2[0]所指向的第一个元素 *var==var[0]这两个是等价的

user: user-2
content: 理解和讨论之前请先学会如何观察！

user: user-3
content: LZ已经理解了指针就是内存地址。内存里面的数据都是一个字节一个字节存放的，程序用特定的方式去访问内存中的这些字节。 所以你的两个问题都是语法规定的访问方式而已。你可以自己看一下教材中关于字符串和字符的部分。 LZ能够问出这两个问题，说明距离掌握指针已经不远了。

user: user-4
content: 引用 15 楼 a491057947 的回复:[quote=引用 8 楼 dalianzsl 的回复:] 1.关于疑问1，想详细了解，可以查看printf的实现代码，其实没必要。printf输出字符串时需要一个地址，可是字符串的长度却是未知的，那么它只能从，所提供的地址开始，连续输出字符，直到遇到'\0'输出结束。因此，你的第一个例子，就如一楼所说的，是有问题的。 char var[]={'a','b','c', '\0'}; printf("%s", var); 写成这样才能正常输出。 2.关于疑问2，数组var2中存储的是字符串指针，也就是char *类型，输出这个数组的第一个元素，直接写 printf("%s", var2[0]); 就可以。*var2[0]这种写法，var2[0]表示数组的第一个元素，也就是指向"aaa"的字符串指针，或者说是"aaa"的首地址。*在这里表示取地址处的值，那么*var2[0]表示取"aaa"首地址处的值，也就是字符'a'。   但在我的机器上可以运行啊 Ubuntu 11[/quote] 你的第一个例子运行时可能报错，也可能不报错，与运行时环境有关。因为定义数组时，最后没有加'\0‘，那么程序会从var这个地址开始，连续输出字符，直到在内存中遇到'\0'结束，因此输出的结果可能是abc、abc一堆其他字符或者访问了不允许访问的内存引起错误。

user: user-5
content: 引用 16 楼 a491057947 的回复:[quote=引用 2 楼 dbzhang800 的回复:] *var2[0] ，类型是char，所以只能是一个字符  var[0]  <==> *(var+0)  <==> *(0+var)  <==> 0[var] <==> *var  0[var]----这个表示没看明白。。[/quote] 第一个问题不建议你用编译器去试(因为测试的结果有无数种答案，而且没什么用)，但这个东西你是真的可以去试了(如果你有兴趣)，试过就有感觉了。

user: user-0
content: 引用 2 楼 dbzhang800 的回复:*var2[0] ，类型是char，所以只能是一个字符  var[0]  <==> *(var+0)  <==> *(0+var)  <==> 0[var] <==> *var  0[var]----这个表示没看明白。。

user: user-0
content: 引用 8 楼 dalianzsl 的回复:1.关于疑问1，想详细了解，可以查看printf的实现代码，其实没必要。printf输出字符串时需要一个地址，可是字符串的长度却是未知的，那么它只能从，所提供的地址开始，连续输出字符，直到遇到'\0'输出结束。因此，你的第一个例子，就如一楼所说的，是有问题的。 char var[]={'a','b','c', '\0'}; printf("%s", var); 写成这样才能正常输出。 2.关于疑问2，数组var2中存储的是字符串指针，也就是char *类型，输出这个数组的第一个元素，直接写 printf("%s", var2[0]); 就可以。*var2[0]这种写法，var2[0]表示数组的第一个元素，也就是指向"aaa"的字符串指针，或者说是"aaa"的首地址。*在这里表示取地址处的值，那么*var2[0]表示取"aaa"首地址处的值，也就是字符'a'。   但在我的机器上可以运行啊 Ubuntu 11

user: user-5
content: 引用 12 楼 a491057947 的回复:[quote=引用 1 楼 dbzhang800 的回复:] 首先，你的疑问一 中举得例子是错的。  你运行过吗？我的环境Ubuntu 11 OK[/quote] 呵呵，现在你还没看出来错误吗？   另外，运行是不能解决问题的，因为这样错误的代码，在某些时候某次运行时，真的可能得到正确的结果，更何况，即使结果明显是错的，可能你都会忽略。

user: user-0
content: 引用 10 楼 u013162593 的回复:1、var指的是这个数组的地址，它的值正好等于数组中第一个元素var[0]的地址。它们地址的值相等，但代表的意思不同。 var代表的是整个数组的地址，&var{0}则是首个元素的地址。 你把var加1之后，发现它跳的长度是一个数组的长度，而把&var[0加1跳转的长度是一个元素的长度 2、var2[0]是什么？它是指针，它本身并不是“aaa”,，而是一个指向“aaa”的指针，也就是，它是指向存放“aaa”这片内存的指针，它只是地址而已。  var仍代表首地址，可见C program language  Page 81

user: user-0
content: 引用 1 楼 dbzhang800 的回复:首先，你的疑问一 中举得例子是错的。  你运行过吗？我的环境Ubuntu 11 OK

user: user-0
content: 引用 4 楼 user-10 的回复:[quote=引用 楼主 a491057947 的回复:]  疑问1：定义一个字符数组 char var[]={'a','b','c'}，这里的数组名为该数组的首地址。当执行printf("%s",var)时可输出全部字符a,b,c，为什么打印首地址可以输出所有字符？  疑问2：定义一个字符指针数组 char *var2[]={"aaa","bbb","ccc"}，表示一个一维数组内存放着三个指针变量，他们指向的内容分别为“aaa”,"bbb","ccc"（这个是C program language 中讲的），所以*var2[0]应该为指针var2[0]所指向的内容，为“aaa”，但测试结果却是"a"(在字符数组中，*var与var[0]的输出一样都为”a“)为什么？ 1.  当printf以%s格式输出字符串时，要求对应参数为字符串的首地址，这是函数接口问题，函数就是这样设计的，使用者必须按这个要求提供参数才能得到正确的结果 2. char *var2[]={"aaa","bbb","ccc"}      var2[0]为char *类型，指向字符串"aaa"      *var2[0]为char类型，指向字符串"aaa"的第一个字符'a'      两者地址值相同，但类型不同，使用时是根据类型来使用的，这一点是关键      [/quote]  恩，你说的有道理，我懂了。

user: user-6
content: 引用 楼主 a491057947 的回复:疑问1：定义一个字符数组 char var[]={'a','b','c'}，这里的数组名为该数组的首地址。当执行printf("%s",var)时可输出全部字符a,b,c，为什么打印首地址可以输出所有字符？  疑问2：定义一个字符指针数组 char *var2[]={"aaa","bbb","ccc"}，表示一个一维数组内存放着三个指针变量，他们指向的内容分别为“aaa”,"bbb","ccc"（这个是C program language 中讲的），所以*var2[0]应该为指针var2[0]所指向的内容，为“aaa”，但测试结果却是"a"(在字符数组中，*var与var[0]的输出一样都为”a“)为什么？  printf中%s期望char *，而char *和char []基本等价；当然一中的例子有越界的隐患。  var2[0]是个char *，然后再解引用，只能得到一个char。

user: user-7
content: 第一个，数组是连续存放的，你只要找到第一个的地址，就可以了 第二个，你的类型是char型，当然是一个字符了

user: user-8
content: 1、var指的是这个数组的地址，它的值正好等于数组中第一个元素var[0]的地址。它们地址的值相等，但代表的意思不同。 var代表的是整个数组的地址，&var{0}则是首个元素的地址。 你把var加1之后，发现它跳的长度是一个数组的长度，而把&var[0加1跳转的长度是一个元素的长度 2、var2[0]是什么？它是指针，它本身并不是“aaa”,，而是一个指向“aaa”的指针，也就是，它是指向存放“aaa”这片内存的指针，它只是地址而已。

user: user-9
content: 引用 7 楼 zhao4zhong1 的回复:[quote=引用 6 楼 syrchina 的回复:] [quote=引用 3 楼 zhao4zhong1 的回复:] 十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495  老赵，还要10个积分，有意思吗？！[/quote]  闲着也是闲着。[/quote]  我的积分。。。

user: user-4
content: 1.关于疑问1，想详细了解，可以查看printf的实现代码，其实没必要。printf输出字符串时需要一个地址，可是字符串的长度却是未知的，那么它只能从，所提供的地址开始，连续输出字符，直到遇到'\0'输出结束。因此，你的第一个例子，就如一楼所说的，是有问题的。 char var[]={'a','b','c', '\0'}; printf("%s", var); 写成这样才能正常输出。 2.关于疑问2，数组var2中存储的是字符串指针，也就是char *类型，输出这个数组的第一个元素，直接写 printf("%s", var2[0]); 就可以。*var2[0]这种写法，var2[0]表示数组的第一个元素，也就是指向"aaa"的字符串指针，或者说是"aaa"的首地址。*在这里表示取地址处的值，那么*var2[0]表示取"aaa"首地址处的值，也就是字符'a'。

user: user-2
content: 引用 6 楼 syrchina 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495  老赵，还要10个积分，有意思吗？！[/quote]  闲着也是闲着。

user: user-9
content: 引用 3 楼 zhao4zhong1 的回复:十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495  老赵，还要10个积分，有意思吗？！

user: user-9
content: 这是一个指针、地址、内容的问题，其实很简单只是你现在搞混了，看下这个资料： http://www.doc88.com/p-907976424060.html

user: user-10
content: 引用 楼主 a491057947 的回复:疑问1：定义一个字符数组 char var[]={'a','b','c'}，这里的数组名为该数组的首地址。当执行printf("%s",var)时可输出全部字符a,b,c，为什么打印首地址可以输出所有字符？  疑问2：定义一个字符指针数组 char *var2[]={"aaa","bbb","ccc"}，表示一个一维数组内存放着三个指针变量，他们指向的内容分别为“aaa”,"bbb","ccc"（这个是C program language 中讲的），所以*var2[0]应该为指针var2[0]所指向的内容，为“aaa”，但测试结果却是"a"(在字符数组中，*var与var[0]的输出一样都为”a“)为什么？ 1.  当printf以%s格式输出字符串时，要求对应参数为字符串的首地址，这是函数接口问题，函数就是这样设计的，使用者必须按这个要求提供参数才能得到正确的结果 2. char *var2[]={"aaa","bbb","ccc"}      var2[0]为char *类型，指向字符串"aaa"      *var2[0]为char类型，指向字符串"aaa"的第一个字符'a'      两者地址值相同，但类型不同，使用时是根据类型来使用的，这一点是关键