Base Address of your Array a + (index of array *size of(data type for array a))
Base Address of your Array a + (5*size of(data type for array a))
i.e. 1000 + (5*2) = 1010
这个解释也是为什么数组中的负索引在 C 语言中工作的原因; 也就是说,如果我访问 a[-5],它会给我:
Base Address of your Array a + (index of array *size of(data type for array a))
Base Address of your Array a + (-5 * size of(data type for array a))
i.e. 1000 + (-5*2) = 990
* A string looks like this:
*
* @code
* [_Rep]
* _M_length
* [basic_string<char_type>] _M_capacity
* _M_dataplus _M_refcount
* _M_p ----------------> unnamed array of char_type
* @endcode
*
* Where the _M_p points to the first character in the string, and
* you cast it to a pointer-to-_Rep and subtract 1 to get a
* pointer to the header.
*
* This approach has the enormous advantage that a string object
* requires only one allocation. All the ugliness is confined
* within a single %pair of inline functions, which each compile to
* a single @a add instruction: _Rep::_M_data(), and
* string::_M_rep(); and the allocation function which gets a
* block of raw bytes and with room enough and constructs a _Rep
* object at the front.
*
* The reason you want _M_data pointing to the character %array and
* not the _Rep is so that the debugger can see the string
* contents. (Probably we should add a non-inline member to get
* the _Rep for the debugger to use, so users can check the actual
* string length.)
*
* Note that the _Rep object is a POD so that you can have a
* static <em>empty string</em> _Rep object already @a constructed before
* static constructors have run. The reference-count encoding is
* chosen so that a 0 indicates one reference, so you never try to
* destroy the empty-string _Rep object.
*
* All but the last paragraph is considered pretty conventional
* for a C++ string implementation.
//使用前面的概念,编写一个示例 C 代码
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct HEAD {
int f1;
int f2;
}S_HEAD;
int main(int argc, char* argv[]) {
int sz = sizeof(S_HEAD) + 20;
S_HEAD* ha = (S_HEAD*)malloc(sz);
if (ha == NULL)
return -1;
printf("&ha=0x%x\n", ha);
memset(ha, 0, sz);
ha[0].f1 = 100;
ha[0].f2 = 200;
// move to user data, can be converted to any type
ha++;
printf("&ha=0x%x\n", ha);
*(int*)ha = 399;
printf("head.f1=%i head.f2=%i user data=%i\n", ha[-1].f1, ha[-1].f2, *(int*)ha);
--ha;
printf("&ha=0x%x\n", ha);
free(ha);
return 0;
}
$ gcc c1.c -o c1.o -w
(no warning)
$ ./c1.o
&ha=0x13ec010
&ha=0x13ec018
head.f1=100 head.f2=200 user data=399
&ha=0x13ec010