小程序,找个错.谢谢

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小程序,找个错.谢谢相关的知识,希望对你有一定的参考价值。

#include<stdio.h>
void main()

char a[5][10],**p;
for(p=a;p<a+5;p++)
gets(*p);
for(p=a;p<a+5;p++)
puts(*p);

不停地输入,还提示有可疑指针.请问是怎么回事?
#include<stdio.h>
int main()

char a[10],*p;
p=a;
gets(p);
puts(p);

这个p也没有指向数组啊,也是指一个char变量,为什么可以进行输入?
这和char **p,a[5][10];
p=a;
有什么区别?p不是已经定义成二级指针了嘛?不太懂啊.帮我下,我再加点分.

改成这样,编译器就不警告了。

#include<stdio.h>
int main()

char a[5][10];
char (*p)[10];
for(p=a;p<a+5;p++)
gets(*p);
for(p=a;p<a+5;p++)
puts(*p);


char **p,意为p是个指针,它将指向一另一个char指针,该指针指向一个char变量。而不是指向一个char数组。

我也不知道,《The C Puzzle Book》第113页说:一个数组的地址和这个数组中的第一个元素的地址是有区别的:这两种地址的类型是不同的,这种区别主要体现在对地址进行算术运算时的递增量/递减量方面.

比如int a[3][3],a的类型是指向三元数组的指针,a的基类型是三元int数组,而a+1将指向下一个三元int数组。a[0]的类型是指向int整数的指针,a[0]的基类型是int,而a[0]+1将指向内存中的下一个int整数。

这也许能解释为什么编译器会对p=a给出警告,而非错误。不过将p声明成char (*p)[10]更好。
/*****************************************/
上面的解释不完全正确,这里有个和你问的是一样的问题,它由Sun Miscosystems公司的Peter van der Linden先生在其大作《Expert C Programming》中作为第二章例子给出了详细的解释。

Reading the ANSI C Standard for Fun, Pleasure, and Profit
Sometimes it takes considerable concentration to read the ANSI C Standard and obtain an answer
from it. A sales engineer sent the following piece of code into the compiler group at Sun as a test case.
1 foo(const char **p)
2
3 main(int argc, char **argv)
4
5 foo(argv);
6
If you try compiling it, you'll notice that the compiler issues a warning message, saying:
line 5: warning: argument is incompatible with prototype
The submitter of the code wanted to know why the warning message was generated, and what part of
the ANSI C Standard mandated this. After all, he reasoned,
argument char *s matches parameter const char *p
This is seen throughout all library string functions.
So doesn't argument char **argv match parameter const char **p ?
The answer is no, it does not. It took a little while to answer this question, and it's educational in more
than one sense, to see the process of obtaining the answer. The analysis was carried out by one of
Sun's "language lawyers," [6] and it runs like this:
[6] The New Hacker's Dictionary defines a language lawyer as "a person who will show you the five
sentences scattered through a 200-plus-page manual that together imply the answer to your question 'if only
you had thought to look there.'" Yep! That's exactly what happened in this case.
The Constraints portion of Section 6.3.2.2 of the ANSI C Standard includes the phrase:
Each argument shall have a type such that its value may be assigned to an object with the unqualified
version of the type of its corresponding parameter.
This says that argument passing is supposed to behave like assignment.
Thus, a diagnostic message must be produced unless an object of type const char ** may be
assigned a value of type char **.To find out whether this assignment is legal, flip to the section
on simple assignment, Section 6.3.16.1, which includes the following constraint:
One of the following shall hold:…
• Both operands are pointers to qualified or unqualified versions of compatible types, and the
type pointed to by the left has all the qualifiers of the type pointed to by the right.
It is this condition that makes a call with a char * argument corresponding to a const char *
parameter legal (as seen throughout the string routines in the C library). This is legal because in the
code
char * cp;
const char *ccp;
ccp = cp;
• The left operand is a pointer to "char qualified by const".
• The right operand is a pointer to "char" unqualified.
• The type char is a compatible type with char, and the type pointed to by the left operand
has all the qualifiers of the type pointed to by the right operand (none), plus one of its own
(const).
Note that the assignment cannot be made the other way around. Try it if you don't believe me.
cp = ccp; /* results in a compilation warning */
Does Section 6.3.16.1 also make a call with a char ** argument corresponding to a const
char ** parameter legal? It does not.
The Examples portion of Section 6.1.2.5 states:
The type designated "const float *" is not a qualified type—its type is "pointer to const-qualified float"
and is a pointer to a qualified type.
Analogously, const char ** denotes a pointer to an unqualified type. Its type is a pointer to a
pointer to a qualified type.
Since the types char ** and const char ** are both pointers to unqualified types that are
not the same type, they are not compatible types. Therefore, a call with an argument of type char
** corresponding to a parameter of type const char ** is not allowed. Therefore, the
constraint given in Section 6.3.2.2 is violated, and a diagnostic message must be produced.
This is a subtle point to grasp. Another way of looking at it is to note that:
• the left operand has type FOO2—a pointer to FOO, where FOO is an unqualified pointer to a
character qualified by the const qualifier, and
• the right operand has type BAZ2—a pointer to BAZ, where BAZ is an unqualified pointer to
a character with no qualifiers.
FOO and BAZ are compatible types, but FOO2 and BAZ2 differ other than in qualifica-tion of the
thing immediately pointed to and are therefore not compatible types; therefore the left and right
operands are unqualified pointers to types that are not compatible. Compatibility of pointer types is
not transitive. Therefore, the assignment or function call is not permitted. However, note that the
restriction serves mainly to annoy and confuse users. The assignment is currently allowed in C++
translators based on cfront (though that might change).
Handy Heuristic
Const Isn't
The keyword const doesn't turn a variable into a constant! A symbol with the const
qualifier merely means that the symbol cannot be used for assignment. This makes the value
re ad -onl y through that symbol; it does not prevent the value from being modified through
some other means internal (or even external) to the program. It is pretty much useful only
for qualifying a pointer parameter, to indicate that this function will not change the data that
argument points to, but other functions may. This is perhaps the most common use of
const in C and C++.
A const can be used for data, like so:
const int limit = 10;
and it acts somewhat as in other languages. When you add pointers into the equation, things
get a little rough:
const int * limitp = &limit;
int i=27;
limitp = &i;
This says that limitp is a pointer to a constant integer. The pointer cannot be used to
change the integer; however, the pointer itself can be given a different value at any time. It
will then point to a different location and dereferencing it will yield a different value!
The combination of const and * is usually only used to simulate call-by-value for array
parameters. It says, "I am giving you a pointer to this thing, but you may not change it."
This idiom is similar to the most frequent use of void *. Although that could
theoretically be used in any number of circumstances, it's usually restricted to converting
pointers from one type to another.
Analogously, you can take the address of a constant variable, and, well, perhaps I had better
not put ideas into people's heads. As Ken Thompson pointed out, "The const keyword
only confuses library interfaces with the hope of catching some rare errors." In retrospect,
the const keyword would have been better named readonly.
True, this whole area in the standard appears to have been rendered into English from Urdu via Danish
by translators who had only a passing familiarity with any of these tongues, but the standards
committee was having such a good time that it seemed a pity to ruin their fun by asking for some
simpler, clearer rules.
We felt that a lot of people would have questions in the future, and not all of them would want to
follow the process of reasoning shown above. So we changed the Sun ANSI C compiler to print out
more information about what it found incompatible. The full message now says:
Line 6: warning: argument #1 is incompatible with prototype:
prototype: pointer to pointer to const char : "barf.c", line
1
argument : pointer to pointer to char
Even if a programmer doesn't understand why, he or she will now know what is incompatible

参考资料:《Expert C Programming》Chapter2

参考技术A #include<stdio.h>
int main()

char a[10],*p;
p=&a;
printf(p);

程序为什么要弄得那么复杂?????
参考技术B 看著有点问题

以上是关于小程序,找个错.谢谢的主要内容,如果未能解决你的问题,请参考以下文章

找个程序员老公,爽!爽!爽!

微信小程序怎么打开地理位置 很急 谢谢!!!

用PHP编写小程序。求大侠帮忙、谢谢

开通加入支付宝小程序怎么收费

记录一下支付宝小程序的坑

微信小程序的阿里云服务器怎么配置,里面的环境怎么搭建,谁有视频教程谢谢!