草庐IT

澄清 C 中指针的左值、右值行为

codeneng 2023-03-28 原文

Clarification over lvalue , rvalue behaviour of pointers in C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<stdio.h>

int main()
{
    int i = 10;
    int *p = &i;

    printf("\
address of initialized pointer p: %u \
"
, p);
    p = &(*p);
    printf("\
modified address of initialized pointer p:%u value:%d valuez address: %d \
"
, p, *p, &(*p));

    return 0;
}

代码输出:-

初始化指针p的地址:3221221820

初始化指针p的修改地址:3221221820 value:10 valuez地址:-1073745476

为什么是"


您在 printf 中使用了不正确的格式说明符。使用 %d 打印地址将不起作用。而是使用 %p 。 [打印地址的%u也不正确。]

这符合预期。

  • %p 和 %u 之间有什么区别?
  • %u 用于打印无符号整数,%p 用于指针。
  • 谢谢 Prasoon,还有一个疑问,当我使用 %p 时,我得到 0x7fbffff1bc,但是当我将 %u - 3221221820 打印的值转换为十六进制时,我只得到 bffff1bc。那么当我使用 %p 时附加的这个额外的 0x7f 是什么?
  • @Saran:在这种情况下,该值以十六进制格式表示。因此,0x
  • @Saran,指针和 unsigned 的宽度可能不同。
  • @Prasoon,不仅 "0x" 被添加为前缀,而且 "0x7f" 被添加为前缀!这是什么7f?
  • @Jens,好的,所以未签名的宽度可能较小,因此缺少 7f 是吗?所以 %p 打印的值是正确的,对吗?
  • @Saran:地址的一部分(以十六进制格式表示)


你有

当您第二次尝试打印地址时,使用

%d 而不是 %u

请注意以下修改后的源代码中的粗体更改:

printf("\
modified address of
initialized pointer p:%u value:%d
valuez address: %u \
", p, *p,
&(*p));

最值得注意的是,您应该使用 %p 来打印指针值,而不是 %u,正如在此线程的另一个答案中已经指出的那样。


指针的标准格式说明符是%p。为了安全起见,您应该始终在对 printf 的调用中明确地将指向 (void*) 的指针强制转换。不保证任何其他格式说明符都可以使用指针值。

例如

1
2
printf("p: %p; *p: %d; &(*p): %p \
"
, (void*)p, *p, (void*)&(*p));

您看到的区别只是第一个格式说明符是 %u ,它将指针值打印为无符号整数,而第二次使用 %d 将其打印为有符号整数。

  • 如果该值已经是一个指针,那么将其转换为 void* 有什么区别?我可以看到将其保留在 C 中的问题(继承和运算符重载可能会导致问题),但是是什么使它在 C 中变得危险?
  • @cHao:虽然不常见,但指向不同类型的指针在 C 中可以有不同的表示形式。 %p 格式说明符要求相应参数的类型为 "pointer to void" 因此,如果您拥有的变量是指向别的东西那么严格你需要转换它以满足 printf 的要求。

有关澄清 C 中指针的左值、右值行为的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  3. ruby-on-rails - Ruby 中意外的大小写行为 - 2

    我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。

  4. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

  5. ruby - 了解在 Ruby 中与 lambda 一起使用的 inject 行为 - 2

    我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject

  6. ruby - 奇怪的 ruby​​ for 循环行为(为什么这样做有效) - 2

    defreverse(ary)result=[]forresult[0,0]inaryendresultendassert_equal["baz","bar","foo"],reverse(["foo","bar","baz"])这行得通,我想了解原因。有什么解释吗? 最佳答案 如果我使用each而不是for/in重写它,它看起来像这样:defreverse(ary)result=[]#forresult[0,0]inaryary.eachdo|item|result[0,0]=itemendresultendforainb基本上就

  7. ruby - 比较 rspec 中的 float 时的奇怪行为 - 2

    以下测试中的第3个失败:specify{(0.6*2).shouldeql(1.2)}specify{(0.3*3).shouldeql(0.3*3)}specify{(0.3*3).shouldeql(0.9)}#thisonefails这是为什么呢?这是浮点问题还是ruby​​或rspec问题? 最佳答案 从rspec-2.1开始specify{(0.6*2).shouldbe_within(0.01).of(1.2)}在那之前:specify{(0.6*2).shouldbe_close(1.2,0.01)}

  8. ruby - 为什么 `Symbol#match` 的行为与 `String#match` 和 `Regexp#match` 不同? - 2

    String#match和Regexp#match在匹配成功时返回一个MatchData:"".match(//)#=>#//.match("")#=>#//.match(:"")#=>#但是Symbol#match返回匹配位置(如String#=~)::"".match(//)#=>0为什么Symbol#match表现不同?有用例吗? 最佳答案 我将其报告为Ruby核心中的错误:https://bugs.ruby-lang.org/issues/11991.让我们看看他们会怎么说。更新被质疑的行为似乎是一个错误。似乎从Ruby2.

  9. ruby - Rails 3 应用程序的 respond_with 语法有奇怪的行为吗? - 2

    在为提供json的Rails3.0.3应用构建API时,发生了一些意外行为。以下是Controller。问题是关于respond_with。我已经在应用程序Controller中有respond_to:json。createAction正常运行,创建后数据也被发回。但是更新操作的respond_with不会发回任何数据。响应主体为空白。defcreateline=get_lineinput_header=line.input_headers.create(params[:input_header])respond_with(input_header,:location=>api_v1_

  10. arrays - 数组元素赋值的奇怪行为 - 2

    今天我遇到了数组元素赋值的一些奇怪行为:arr=["a","b"]arr2=[1,2]arr.unshift(arr2)#=[[1,2],"a","b"]arr.push(arr2)#=>["a","b",[1,2]]但是,这是有道理的:arr[0,0]=arr2#=>[1,2,"a","b"]我知道在[0,0]中,第一个零是index,第二个是该数组中从index开始的元素数。在我看来它应该与unshift相同,但事实并非如此。谁能解释一下这种行为? 最佳答案 如果我们diveintotherubysourcecode,我们会找到

随机推荐