据说在 C 中,当指针指向同一个数组或该数组末尾之后的一个元素时,算术和比较是明确定义的。那么数组第一个元素之前的一个呢?只要我不取消引用就可以了吗?
给定的
int a[10], *p;
p = a;
Run Code Online (Sandbox Code Playgroud)
(1) 写字合法--p吗?
(2)p-1在表达式中写入是否合法?
(3) 如果 (2) 没问题,我可以断言p-1 < a吗?
对此有一些实际的担忧。考虑一个reverse()函数,它反转以 结尾的 C 字符串'\0'。
#include <stdio.h>
void reverse(char *p)
{
char *b, t;
b = p;
while (*p != '\0')
p++;
if (p == b) /* Do I really need */
return; /* these two lines? */
for (p--; b < p; b++, p--)
t = *b, *b = *p, *p …Run Code Online (Sandbox Code Playgroud) 为什么两个地址之间的区别是错误的? http://codepad.org/NGDqFWjJ
#include<stdio.h>
int main()
{
int i = 10, j = 20;
int *p = &i;
int *q = &j;
int c = p - q;
printf("%d\n", p);
printf("%d\n", q);
printf("%d", c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
-1083846364
-1083846368
1
Run Code Online (Sandbox Code Playgroud) #include <stdio.h>
int main() {
int i,n;
int a = 123456789;
void *v = &a;
unsigned char *c = (unsigned char*)v;
for(i=0;i< sizeof a;i++) {
printf("%u ",*(c+i));
}
char *cc = (char*)v;
printf("\n %d", *(cc+1));
char *ccc = (char*)v;
printf("\n %u \n", *(ccc+1));
}
Run Code Online (Sandbox Code Playgroud)
该程序在我的32位Ubuntu机器上生成以下输出.
21 205 91 7
-51
4294967245
Run Code Online (Sandbox Code Playgroud)
前两行输出我能理解=>
请解释最后一行输出.为什么添加三个1的字节,因为(11111111111111111111111111001101) = 4294967245.
这更像是一个关于 C++ 的好奇问题,是在学习如何查找迭代器引用的索引后提出的。
给定两个向量迭代器,为什么它们可以相减但不能相加?
例如,为什么要编译和运行:
std::vector<int> vect;
vect.begin() - vect.end();
Run Code Online (Sandbox Code Playgroud)
虽然这不会:
std::vector<int> vect;
vect.begin() + vect.end();
Run Code Online (Sandbox Code Playgroud)
问题是更好地了解迭代器的行为方式。对于那些评论和回答的人,谢谢!我需要更多地研究指针算法才能理解这一点。
我认为最有帮助的答案是迭代器就像指针。
减去两个指针来得到它们的距离差是有道理的,就像在数轴上看 1-10 并想要 7 和 3 之间的距离,你从 3 中减去 7 得到 4 的距离。
将 7 和 3 相加得到 10,这并不能帮助我找到它们之间的距离,并且在容器中最终会指向容器边界之外的东西,这没有帮助或有用。
c++ iterator operator-overloading pointer-arithmetic stdvector
在2005年11月1日的C++专栏中,Herb Sutter写道......
int A[17];
int* endA = A + 17;
for( int* ptr = A; ptr < endA; ptr += 5 )
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
[O]在某些CPU架构(包括当前的架构)中,上述代码可能导致硬件陷阱发生在创建三个结束指针的位置,无论该指针是否被解除引用.
如何在bitpattern上捕获CPU?关于什么 ...
int A[17];
// (i) hardware will trap this ?
int *pUgly = A + 18;
// (ii) hardware will trap this, too?
int *pEnd = A + 17;
++pEnd;
// (iii) will this fool it?
int *precious = A + 17;
unsigned long tricksy = reinterpret_cast<unsigned long>(precious) ;
++tricksy; …Run Code Online (Sandbox Code Playgroud) 我对此代码感到困惑:(http://www.joelonsoftware.com/articles/CollegeAdvice.html)
while (*s++ = *t++);
Run Code Online (Sandbox Code Playgroud)
执行的顺序是什么?是*s =*t首先完成,然后它们各自递增?或者其他方式?
谢谢.
编辑:如果是这样的话:
while(*(s++) = *(t++));
Run Code Online (Sandbox Code Playgroud)
和
while(++*s = ++*t);
Run Code Online (Sandbox Code Playgroud) 如果我说,
int a[] = {1, 2, 3, 4, 5};
int *p = a;
Run Code Online (Sandbox Code Playgroud)
现在,如果我写的话p + 1 + 2会和它一样((p + 1) + 2)吗?任何证明这个错误的标准参考?
现在我们知道,越界 - 指针算术具有未定义的行为,如本SO问题所述.
我的问题是:我们可以通过转换为std :: uintptr_t进行算术运算然后转换回指针来解决这种限制吗?是保证工作吗?
例如:
char a[5];
auto u = reinterpret_cast<std::uintptr_t>(a) - 1;
auto p = reinterpret_cast<char*>(u + 1); // OK?
Run Code Online (Sandbox Code Playgroud)
真实世界的用法是优化偏移内存访问 - 而不是p[n + offset]我想做的offset_p[n].
编辑使问题更明确:
给定一个pchar数组的基指针,如果p + n是一个有效的指针,将reinterpret_cast<char*>(reinterpret_cast<std::uintptr_t>(p) + n)保证产生相同的有效指针?
对于我需要做的以下事情,我遇到了很大的困难:
a.声明包含有理数的数据结构.
湾 写f'xns将+, - ,*,/有理数.
所有f'xns必须传递3个参数,每个参数指向在a部分中声明的类型I的数据结构; 2个参数=操作数,第3个=结果.
C.编写一个f'xn,它将指向数据结构的指针作为参数,并返回数字的GCD.&denom.
d.使用c部分中的f'xn来编写一个将分数(有理数)减少到最低项的f'xn.传入指向分数的指针,并用f'xn修改分数.
即 写入输入和输出功能,以便用户可以以1/5的形式输入分数.
应允许用户输入任意数量的问题,程序应以最低的条件输出答案.
我是在正确的轨道上吗?我相信我有下降,但不是d,尤其是e.有人可以指导我或帮我纠正我的剧本吗?
int GCD (int numer, int denom)
{
int result;
while (denom > 0) {
result = numer % denom;
numer = denom;
denom = result;
}
return numer;
}
int getLCM (int numer, int denom)
{
int max;
max = (numer > denom) ? numer : denom;
while (1) {
if (max % numer == 0 && max % denom == 0)
break; …Run Code Online (Sandbox Code Playgroud) 我有一个结构数组,我有一个指向其中一个结构的成员的指针.我想知道数组的哪个元素包含该成员.这有两种方法:
#include <array>
#include <string>
struct xyz
{
float x, y;
std::string name;
};
typedef std::array<xyz, 3> triangle;
// return which vertex the given coordinate is part of
int vertex_a(const triangle& tri, const float* coord)
{
return reinterpret_cast<const xyz*>(coord) - tri.data();
}
int vertex_b(const triangle& tri, const float* coord)
{
std::ptrdiff_t offset = reinterpret_cast<const char*>(coord) - reinterpret_cast<const char*>(tri.data());
return offset / sizeof(xyz);
}
Run Code Online (Sandbox Code Playgroud)
这是一个测试驱动程序:
#include <iostream>
int main()
{
triangle tri{{{12.3, 45.6}, {7.89, 0.12}, {34.5, 6.78}}};
for (const …Run Code Online (Sandbox Code Playgroud)