没有更多令人困惑的指针
No More Confusing Pointers
以下是我的代码:
#include <stdio.h>
int main()
{
char a[10]="Hi!";
void f(char b[])
{
// 1. printf("*a is:%s\n",*a);
printf("&a is:%p\n",&a);
// 2. printf("&&a is:%p\n",&(&a));
printf("a's address is:%p\n",a);
printf("a's value is:%s\n",a);
printf("b's address is:%p\n",b);
printf("b's value is:%s\n",b);
// 3. printf("*b is:%s\n",*b);
printf("&b is:%s\n",&b);
}
f(a);
return 1;
getch();
}
运行 上面的代码给出了输出:
&a is:0028FF1C
a's address is:0028FF1C
a's value is:Hi!
b's address is:0028FF1C
b's value is:Hi!
&b is:∟ (
在输出中:
为什么 &a
和 &b
有不同的输出;
尽管 a 和 b 具有相同的引用。
此外,
我已经按编号提到了 3 条评论。
如果我一个一个地删除斜杠并执行它们,我会遇到以下 2 个问题:
在执行评论号。 1 & 3:
"abc.exe has stopped working."
在执行评论号。 2:
abc.c: In function 'f':
abc.c:14:32: error: lvalue required as unary '&' operand
printf("&&a is:%p\n",&(&a));
^
您复制粘贴了 printf()
并且没有更改说明符
printf("&b is:%s\n", &b)
/* ^ should be `p' */
第一个注释在执行时会导致问题,因为您正在使用 "%s"
说明符并传递 a
的第一个字符,这将被解释为地址,试试这个
printf("*a is: %c\n", *a);
第三个评论提出了同样的问题。
第二个评论,你需要一个中间指针来做到这一点,比如
char *c = &a;
char **d = &c;
printf("%p\n", (void *) d);
虽然它会打印出与 printf("%p\n", (void *) a);
相同的结果,因为它们都有相同的地址,但不同之处在于指针算法的工作方式不同。
点 1:Nested functions are not standard C
. They are supported as GCC extension.。
点 2: printf("&b is:%s\n",&b);
错误并调用 UB,因为格式说明符不正确。您需要将其更改为
printf("&b is:%p\n",(void *)&b);
第3点:&(&a)
是错误的。 &
的操作数必须是左值,而不是另一个 地址 ,后者不是左值。
相关:C11
,章节§6.5.3.2
,操作数类型
The operand of the unary &
operator shall be either a function designator, the result of a []
or unary *
operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.
和return类型
....result is not an lvalue.
好吧,您不应该在另一个函数中定义函数 - 虽然一些编译器接受这一点(例如 gcc
),但它不可移植。
printf("&b is:%s\n",&b);
这里&b
是b
的地址,也就是char数组的地址。实际上 &b 是参数的地址。
1.) 和 3.) 失败,因为您需要传递一个指向字符串的指针。 *a, 是一个取消引用的指针,因此,实际上,它是字符串的第一个字符
2.) &&a 是指向指向指针的指针的指针(因为 a
是 已经是指针。
注:这是问题作者自己的回答,见revision 3
我理解了上述问题,这是改进后的代码:
#include<stdio.h>
#include<string.h>
int i;
char a[11]="F*** Yeahh!"; //String : char *
//'a' gets memory in "globals" area;'a' is a pointer to 'F'
void func();//Function Definition
int main()
{
func(a); //Passing reference of 'a' to func
getch();
return 1;
}
void func(char b[])
//'b' is given memory in 'stack' region;'b' has a reference
// to 'a' which in turn refer to 'F'
{
printf("*a is:%c\n",*a);
printf("&a is:%p\n",&a);
//printf("&&a is:%p\n",&(&a));//&()...Inside braces,there must be a
// value..
printf("a's address is:%p\n",a);
printf("a's value is:%s\n",a);
printf("b's address is:%p\n",b);
printf("b's value is:%s\n",b);
printf("*b is:%c\n",*b);
printf("&b is:%p\n",&b);
for(i=0;i<strlen(a);i++)
printf("String as an array of characters is:%c\n",b[i]);
}
这是输出:
*a is:F
&a is:00409000
a's address is:00409000
a's value is:F*** Yeahh!
b's address is:00409000
b's value is:F*** Yeahh!
*b is:F
&b is:0028FF20
String as an array of characters is:F
String as an array of characters is:*
String as an array of characters is:*
String as an array of characters is:*
String as an array of characters is:
String as an array of characters is:Y
String as an array of characters is:e
String as an array of characters is:a
String as an array of characters is:h
String as an array of characters is:h
String as an array of characters is:!
以下是我的代码:
#include <stdio.h>
int main()
{
char a[10]="Hi!";
void f(char b[])
{
// 1. printf("*a is:%s\n",*a);
printf("&a is:%p\n",&a);
// 2. printf("&&a is:%p\n",&(&a));
printf("a's address is:%p\n",a);
printf("a's value is:%s\n",a);
printf("b's address is:%p\n",b);
printf("b's value is:%s\n",b);
// 3. printf("*b is:%s\n",*b);
printf("&b is:%s\n",&b);
}
f(a);
return 1;
getch();
}
运行 上面的代码给出了输出:
&a is:0028FF1C
a's address is:0028FF1C
a's value is:Hi!
b's address is:0028FF1C
b's value is:Hi!
&b is:∟ (
在输出中:
为什么 &a
和 &b
有不同的输出;
尽管 a 和 b 具有相同的引用。
此外,
我已经按编号提到了 3 条评论。 如果我一个一个地删除斜杠并执行它们,我会遇到以下 2 个问题:
在执行评论号。 1 & 3:
"abc.exe has stopped working."
在执行评论号。 2:
abc.c: In function 'f': abc.c:14:32: error: lvalue required as unary '&' operand printf("&&a is:%p\n",&(&a)); ^
您复制粘贴了 printf()
并且没有更改说明符
printf("&b is:%s\n", &b)
/* ^ should be `p' */
第一个注释在执行时会导致问题,因为您正在使用 "%s"
说明符并传递 a
的第一个字符,这将被解释为地址,试试这个
printf("*a is: %c\n", *a);
第三个评论提出了同样的问题。
第二个评论,你需要一个中间指针来做到这一点,比如
char *c = &a;
char **d = &c;
printf("%p\n", (void *) d);
虽然它会打印出与 printf("%p\n", (void *) a);
相同的结果,因为它们都有相同的地址,但不同之处在于指针算法的工作方式不同。
点 1:Nested functions are not standard
C
. They are supported as GCC extension.。点 2:
printf("&b is:%s\n",&b);
错误并调用 UB,因为格式说明符不正确。您需要将其更改为printf("&b is:%p\n",(void *)&b);
第3点:
&(&a)
是错误的。&
的操作数必须是左值,而不是另一个 地址 ,后者不是左值。相关:
C11
,章节§6.5.3.2
,操作数类型The operand of the unary
&
operator shall be either a function designator, the result of a[]
or unary*
operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.和return类型
....result is not an lvalue.
好吧,您不应该在另一个函数中定义函数 - 虽然一些编译器接受这一点(例如 gcc
),但它不可移植。
printf("&b is:%s\n",&b);
这里&b
是b
的地址,也就是char数组的地址。实际上 &b 是参数的地址。
1.) 和 3.) 失败,因为您需要传递一个指向字符串的指针。 *a, 是一个取消引用的指针,因此,实际上,它是字符串的第一个字符
2.) &&a 是指向指向指针的指针的指针(因为 a
是 已经是指针。
注:这是问题作者自己的回答,见revision 3
我理解了上述问题,这是改进后的代码:
#include<stdio.h>
#include<string.h>
int i;
char a[11]="F*** Yeahh!"; //String : char *
//'a' gets memory in "globals" area;'a' is a pointer to 'F'
void func();//Function Definition
int main()
{
func(a); //Passing reference of 'a' to func
getch();
return 1;
}
void func(char b[])
//'b' is given memory in 'stack' region;'b' has a reference
// to 'a' which in turn refer to 'F'
{
printf("*a is:%c\n",*a);
printf("&a is:%p\n",&a);
//printf("&&a is:%p\n",&(&a));//&()...Inside braces,there must be a
// value..
printf("a's address is:%p\n",a);
printf("a's value is:%s\n",a);
printf("b's address is:%p\n",b);
printf("b's value is:%s\n",b);
printf("*b is:%c\n",*b);
printf("&b is:%p\n",&b);
for(i=0;i<strlen(a);i++)
printf("String as an array of characters is:%c\n",b[i]);
}
这是输出:
*a is:F
&a is:00409000
a's address is:00409000
a's value is:F*** Yeahh!
b's address is:00409000
b's value is:F*** Yeahh!
*b is:F
&b is:0028FF20
String as an array of characters is:F
String as an array of characters is:*
String as an array of characters is:*
String as an array of characters is:*
String as an array of characters is:
String as an array of characters is:Y
String as an array of characters is:e
String as an array of characters is:a
String as an array of characters is:h
String as an array of characters is:h
String as an array of characters is:!