Thi*_*mar 6 programming compiling gcc
我是 linux 新手。我gcc
在 Ubuntu 12.04 LTS 上使用(Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3。当我使用指针编译 c 程序时,我收到-Wformat
如下所示的警告。但是如果我执行a.out
文件,我会得到正确的结果。谁能告诉我为什么我收到这条消息并建议我应该怎么做才能克服?
我的测试程序:
#include<stdio.h>
void main(void)
{
int x=10,y,z;
int *p=&x ;
printf("\n\np = %u\n",p);
printf("\n*p = %u\n",*p);
printf("\n&x = %u\n",&x);
printf("\n&y = %u\n",&y);
printf("\n&z = %u\n",&z);
printf("\n&p = %u\n\n",&p);
}
Run Code Online (Sandbox Code Playgroud)
输出:
qust1-Array.c:11:2: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat]
qust1-Array.c:14:2: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat]
qust1-Array.c:15:2: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat]
qust1-Array.c:16:2: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat]
qust1-Array.c:17:2: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int **’ [-Wformat]
Run Code Online (Sandbox Code Playgroud)
由于你所得到的警告使用了错误的格式说明在printf()
。p
是一个整数指针。&p
是指针的地址。&x
和&y
是整数的地址。这些都是内存中的地址,而不是变量的值。说明符%u
用于无符号整数的值。所以你在编译器需要橙子的地方打印苹果。地址比存储在变量中的某些值短。通过使用%u
实际上会将地址值打印为十进制(非常不寻常)以及位于内存中的更多数据。编译器在抱怨,因为这可能不是您想要做的。要打印地址,请使用说明符%p
,如下所示:
printf("\n&x = %p\n",&x);
Run Code Online (Sandbox Code Playgroud)
除此之外,您的变量是有符号整数,因此应使用%i
代替%u
。的%u
格式说明符printf()
仅适用于正整数。对于小的正值,%i
和%u
可以互换。显示警告是因为变量类型与其说明符不匹配,这在某些情况下会导致问题。
从您的变量类型来看,这会更明智:
printf("\n\np = %p\n", p); // p is a pointer so %p would print the address
printf("\n*p = %i\n", *p); // the data saved at that address is an integer
// so %i is appropriate if you dereference the
// pointer with the star "*p"
printf("\n&x = %p\n", &x); // &x gives the address of the integer variable x
// so %p is the specifier for that address
printf("\n&y = %p\n", &y);
printf("\n&z = %p\n", &z);
printf("\n&p = %p\n\n", &p); // &p gives the address, where the pointer p is
// stored -> still an address -> %p is the right
// specifier
Run Code Online (Sandbox Code Playgroud)
关于有符号和无符号整数和指针的一些背景知识:
C 使用相同的 32 位(或另一种 2 的幂,取决于系统架构)来存储无符号和有符号整数。因此最高值unsigned int
是 2 32 -1 或二进制表示法:
2 32 -1 = (111111111111111111111111111111111) 2 <- (无符号)
数字一在二进制中看起来像这样:
1 = (00000000000000000000000000000001) 2 <- (无符号)
现在常规有符号整数也需要存储负数,但仍然在相同的 32 位空间中。如果您将数字的符号存储在例如第一位中,您将丢失一整位。那会很浪费,例如零将有两种表示形式,即 + 和 - 零。为了规避这个问题,有符号整数中的负数存储方式略有不同:要将数字编码为有符号整数,请将 32 位数字的可能范围减半。这是 2 (32-1),然后使用该新数字的常规二进制表示。所以一个 1 被编码为 2 (32-1) + 1 将是一个无符号整数。我们有:
2 (32-1) = (111111111111111111111111111111111) 2 <-签名
...
1 = (10000000000000000000000000000001) 2 <- 签名
0 = (10000000000000000000000000000000) 2 <- 签名
-1 = (01111111111111111111111111111111) 2 <- 签名
...
-2 (32-1) = (00000000000000000000000000000000) 2 <-签名
现在您已经编码了相同数量的整数,但有符号整数的最大值因此只有 2 (32-1),而不是无符号整数的两倍,2 32 -1。这称为负数的过量 K或偏移二进制表示。大多数系统使用二进制补码,其中第一个最重要的位被反转。
要查看此内容,请设置x=-1;
然后printf("%u",x)
。您将获得以下输出:
2147483648
这是 2 32-1或 (011111111111111111111111111111111) 2二进制表示法。对于 2 的补码,这个数字是:
4294967295
或 2 32 -1。这在二进制中等于 (11111111111111111111111111111111) 2,因此与上面的 2147483648 的超量 K 值相比,它的第一位反转。
因此,这是如何将数据存储。当您想到where时,指针就会发挥作用。内存中的物理位必须有地址。由于它们中的数量令人难以置信,因此您可以分块地解决它们。如果创建一个指针,指针地址处的物理内存将保存内存中的另一个地址。所以房子是一个物理对象,很像你电脑内存中的一点。一张纸就是一个指针。它比房子小,但可以保存房子或其他房子的地址。在那个比喻中,上面你会试图拆除一张纸而不是实际的房子,它实际上是一座山......
归档时间: |
|
查看次数: |
5533 次 |
最近记录: |