b244183
V2EX  ›  C

为什么感觉 C 的常量以及指针相关的语法十分令人费解?

  •  
  •   b244183 · Jan 13, 2016 · 3814 views
    This topic created in 3949 days ago, the information mentioned may be changed or developed.
    常量 常量指针 指向常量的指针 常量 常量指针 指向常量的常量指针

    指针++=++指针 指针++=指针++ ++指针=++指针 *(++指针) *(指针++)

    最近在看 Pointers on C
    感觉这些东西是有规则,但是十分 counterintuitive ,令人费解
    40 replies  •  2016-01-14 15:17:26 +08:00
    wizardoz
    wizardoz
    Jan 13, 2016
    1
    首先你要理解指针是一种类型(或多种类型),常量就是不能改变的变量。

    对于 int 来说
    int 是一种类型 int* 是一种类型,只不过这两种类型略微有一点关系而已。

    const int 就是整型常量
    const int* 就是指向整型常量的指针
    int* const 是指向整型的指针常量
    !! 注意其中的区别,一个是指针本身是常量,就是指针变量不能改,一个是指针不是常量可以改,但是指针指向的内存不能改。

    当然还可以
    const int * const
    指向整型常量的指针长量。
    指针的值也不能改,指针指向的地址的内容也不能改。
    congeec
    congeec
    Jan 13, 2016
    2
    你打开的方式不对

    来,告诉我什么是指针数组,什么是数组指针?
    我不知道,但是一看我就知道下面两行代码是什么意思
    int *p[2];
    int (*p)[2];

    同样地,指针++ = 指针++ 这是什么鬼?
    while (*s++ = *t++); // 不过这行复制字符串的代码你肯定能理解

    概念是抽象过的,一般比原来的东西难理解。写几行代码,抓住本质就行了
    k9982874
    k9982874
    Jan 13, 2016
    3
    理解不了我才表示费解,实在不行就去做前端啥的吧,没有指针。
    7emes
    7emes
    Jan 13, 2016
    4
    @wizardoz 发现一个错别字,倒数第二行。
    b244183
    b244183
    OP
    Jan 13, 2016
    5
    @wizardoz
    @k9982874
    @congeec 我知道这些是做什么用的,也会用,但是疑惑为什么语法要设计成这样,都没什么更直观的做法吗
    f7ee9404
    f7ee9404
    Jan 13, 2016
    6
    就是语法糖, c 设计的时候内存和硬盘单位价格非常高,对应现在的电脑没什么大用 代码怎么容易读怎么搞就行。

    i++ 等价于 i=i+1
    congeec
    congeec
    Jan 13, 2016
    7
    @b244183 为嘛要设计成这样?看 spec 吧: ISO/IEC 9899
    多扯两句,据我所知 C 语言基本上是可移植的汇编,为汇编程序员设计的。
    i++有直接对应的汇编指令 incr i
    在汇编里操作数据只能用地址+偏移,自然而然 C 语言里就有指针这个概念了
    kobe1941
    kobe1941
    Jan 13, 2016
    8
    指针和结构体在一起才坑爹%>_<%
    maomaomao001
    maomaomao001
    Jan 13, 2016 via Android
    9
    @wizardoz 好晕啊~~~为什么 C/C++是这种设计方式....
    MCVector
    MCVector
    Jan 13, 2016
    10
    @maomaomao001 to make your life easier.
    young
    young
    Jan 13, 2016
    11

    想起了前几天看到的这个
    wizardoz
    wizardoz
    Jan 13, 2016
    12
    @maomaomao001 其实从语义来讲很对称啊。整个过程只是变量,指针,和 const 三个概念组合以后发生了许多变化。并且组合以后并没有产生与三个概念矛盾的东西。
    所以不应该说 C/C++设计成这样,应该说 C 语言的设计者没有进行很多的设计和封装,而是直接把事情的本质放出来了。
    maomaomao001
    maomaomao001
    Jan 13, 2016 via Android
    13
    @MCVector 骗子。。。
    dorentus
    dorentus
    Jan 13, 2016 via iPhone
    14
    推荐一本书:《征服C指针》
    Kilerd
    Kilerd
    Jan 13, 2016
    15
    你的 C 功底不行啊,指针其实在 C 里面不算是特别难得吧。
    yurivvvvv
    yurivvvvv
    Jan 13, 2016
    16
    我觉得正是 Pointers on C 把这些费解的东西讲的很清楚了。
    b244183
    b244183
    OP
    Jan 13, 2016
    17
    @wizardoz
    @Kilerd
    @yurivvvvv 我想讨论的是语法层面的设计
    jixiangqd
    jixiangqd
    Jan 13, 2016
    18
    看 const 在*前还是*后,*前则是修饰*,*后则是修饰具体类型

    const int *
    int const *
    int * const //只有这个修饰 int
    chmlai
    chmlai
    Jan 13, 2016
    19
    @b244183 那你有想出更好的设计吗?
    k9982874
    k9982874
    Jan 13, 2016
    20
    @b244183
    你要知道 c/c++的内存操作原理就不会不懂了

    c/c++数据传递默认传值,也就是直接做内存 copy ,操作一次就会产生一个内存 copy

    如果是 int 之类的简单类型就算了,如果是 struct 或 class 之类的大对象那内存多少都不够用

    所以为了解决这个问题引入了指针,指针的大小就是一个 unsiged int 的大小, copy 一个 int 的花销和 copy 一个对象的花销比还是很合算的

    这样就避免了值传递时无穷无尽的内存 copy

    还有什么修改对象值,前 const ,后 const 之类的东西都是额外的知识。
    raysonx
    raysonx
    Jan 13, 2016
    21
    一言以蔽之:指針保存的只是一個整數,和 long 、 int 沒有本質區別,其他皆為語法糖。
    ffffwh
    ffffwh
    Jan 13, 2016 via Android
    22
    “右左法则”

    你还没有见识过 C++的引用、右值引用、指针 /引用与 template 连用等等
    dorentus
    dorentus
    Jan 13, 2016
    23
    我完全不同意 raysonx 的看法

    指针和整数是完全不同概念的东西,只是在 C 里面它刚好用一个特定长度的整数值表示而已(原因和硬件或者汇编的细节以及影响了 C 的设计的那些语言的细节有关)。

    指针的那些加加减减的操作符才是语法糖。正是这些操作符产生了它在逻辑上就是一个整数的假象。但是要明白,指针并不是整数,对它的这些加加减减代表的意义和遵循的规则并不完全和整数的那些一样。
    raysonx
    raysonx
    Jan 13, 2016
    24
    @dorentus 你是在語言的層面上看的。對於 CPU 來講什麼數據類型沒有任何意義,他只會根據你調用指令的不同執行不同的操作。編寫匯編程序的時候,讀內存都是需要傳地址作為操作數的。

    所謂加加減減所代表的意義只是編譯器層面的東西,編譯器會自動把加減法轉為被指向數據類型大小的倍數。這個倍數的値是硬編碼在目標代碼中的。
    iyangyuan
    iyangyuan
    Jan 13, 2016 via iPhone
    25
    因为是给聪明人看的,像我这种愚钝的人只能搞面向对象
    vanxining
    vanxining
    Jan 13, 2016 via Android
    26
    @congeec 第二种是什么意思呢?没看明白。
    vanxining
    vanxining
    Jan 13, 2016 via Android
    27
    哦,查了一下,原来是指向一个固定长度数组的指针。第一次看到。新技能 get√。
    Reficul
    Reficul
    Jan 13, 2016
    28
    指针就是内存地址, C 语言的指针还是很容易理解的,只是容易在 debug 的时候抓狂
    b244183
    b244183
    OP
    Jan 13, 2016
    29
    看了 K&R 的 5.12 Complicated Declarations
    基本搞懂了
    woai110120130
    woai110120130
    Jan 14, 2016 via Android
    30
    我很费解 楼主为什么很费解
    louk78
    louk78
    Jan 14, 2016
    31
    因为是给聪明人看的,像我这种愚钝的人只能搞面向对象
    msg7086
    msg7086
    Jan 14, 2016
    32
    如果你觉得设计得不好,你应该 1972 年的时候就提出来。

    如果没有,那么说明你那时候 —— 要么还没这水平去提意见,要么你还没出生。

    或者两者皆是。
    saeba1030
    saeba1030
    Jan 14, 2016
    33
    对于指针来说,数据类型只是告诉指针应该以什么方式去存取内存里的数据,指针本身无所谓类型。
    cheng4741
    cheng4741
    Jan 14, 2016
    34
    @msg7086 不同意你的观点,如果一个东西设计得不好,不一定能在当时就体现出来。很多东西都是随着时间的推移才发现原来设计的有问题。
    msg7086
    msg7086
    Jan 14, 2016
    35
    @cheng4741 发现有问题就不能随便改了。

    你去看看 Python 3 。
    ma125125t
    ma125125t
    Jan 14, 2016
    36
    @cheng4741 显然,设计的是有问题,不然哪有 OOP 什么事呢?
    chiuup
    chiuup
    Jan 14, 2016
    37
    @saeba1030 准确地说,指针的数据类型是告诉编译器应该怎么样翻译成汇编码,指针本身是有类型的,并且这个类型在编译时很重要。
    chiuup
    chiuup
    Jan 14, 2016
    38
    追溯到源头的话, C 是一帮对汇编代码十分精通的大牛设计的, C 是对汇编码最直接的一层抽象。如果你可以站在汇编程序员的角度来看 C 的这些设计的话,很多 C 的设计就很好理解了。比如说你提到指针算术,其实是对 lea 的一种特定用法的抽象。
    ahbcd112
    ahbcd112
    Jan 14, 2016
    39
    很久很久以前。。。内存是非常非常贵的
    怎样节省怎么用。内存各种算
    内存的增长是指数增加的(比尔不是说过,个人电脑只要 32M 就够了!!某 N 年前电影,里面有一段,机器人能存储他看到的所有东西,因为他有一个非常非常大的硬盘。。。。 500MB )
    然而,开发费用。。。貌似没降多少吧。
    所以 OOP 各种发展,浪费点空间。减少开发、维护工作量。
    lilydjwg
    lilydjwg
    Jan 14, 2016
    40
    @b244183 我曾经看到过有人讲 C 语言的指针和常量语法为什么会是现在这个样子。然而我早已不记得了……
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2713 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 81ms · UTC 13:31 · PVG 21:31 · LAX 05:31 · JFK 08:31
    ♥ Do have faith in what you're doing.