请考虑以下代码片段:
int (*p)[3];
int (*q)[3];
q = p;
q++;
printf("%d, %d\n", q, p);
printf("%d\n", q-p);
Run Code Online (Sandbox Code Playgroud)
我知道指针算法是智能的,这意味着操作q++前进q足够的字节指向下一个3整数数组,所以第一次打印是' 12, 0' 并不意味着递增q使它在12中更大.
但第二次印刷确实令我惊讶.它打印1!
那么为什么它会打印1而不是12?它只是困惑我.
我知道这是真的:
x[4] == 4[x]
Run Code Online (Sandbox Code Playgroud)
多维数组的等价物是什么?以下是真的吗?
x[4][3] == 3[x[4]] == 3[4[x]]
Run Code Online (Sandbox Code Playgroud) 我正在阅读Pointer Arithmetic中的一些内容,我遇到了两件我无法理解的事情,也不知道它的用途
address_expression - address_expression
Run Code Online (Sandbox Code Playgroud)
并且
address_expression > address_expression
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释一下,它们是如何工作的以及何时使用它们.
编辑:
我想说的是,如果我只取两个地址并减去它们,它们会产生什么
如果我拿两个地址并比较它们的结果或基于的比较
编辑:我现在明白了减去地址的结果,但比较地址我仍然没有得到它.
我理解1 <2,但是地址如何比另一个更大,他们在比较什么
我正在做一些关于数组和指针的实验:
int a[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int i = 1, j = 1;
int (*p)[3];
p = a;
printf ("*(*(a + i) + j) = %d\n", *(*(a + i) + j));
printf ("*(a[i] + j) = %d\n", *(a[i] + j));
printf ("*(a + i)[j] = %d\n", *(a + i)[j]);
printf ("*(a + 3 * i + j) = %p\n", *(a + 3 * i + j));
printf ("*(*(p + i) + j) = …Run Code Online (Sandbox Code Playgroud) 尝试打印第一个命令行参数时:
std::cout << argv[0] << std::endl;
Run Code Online (Sandbox Code Playgroud)
clang-tidy发出警告:
警告:[cppcoreguidelines-pro-bounds-pointer-arithmetic]中的'不使用指针运算'
有argv没有使用指针算法的替代方法来使用值?是不是char**通过任何明智的方法访问必须使用指针算术?
我欣赏有一些专门的函数来处理命令行参数,但它们似乎太重了,不能简单地打印一个参数.
我正在编写c++,使用clang编译器和构建cmake.
c++ pointer-arithmetic command-line-arguments clang-static-analyzer clang++
在C的许多搜索函数中(如果找到结果,可以想到bsearch),返回指向数组中点的指针.如何将此指针转换为搜索到的数组中的索引(使用指针算法,我假设).
我正在深入研究指针,因为我不认为我对指针有很好的了解,并在维基百科上看到以下几行:
处理数组时,关键查找操作通常涉及一个称为地址计算的阶段,该阶段涉及构造指向数组中所需数据元素的指针.如果数组中的数据元素具有可被2的幂整除的长度,则此算法通常更有效.
为什么会这样?
我知道指针(指向数组元素)和迭代器可以递增/递减以遍历元素序列,并且可以在序列中来回跳转元素。
但是如果我增加一个指向单个对象的指针或向它添加一个整数值会发生什么?这是未定义的行为还是可以但我们无法访问该内存?
int x = 551;
int* p = &x;
++p;
--p;
std::cout << *p << '\n';
Run Code Online (Sandbox Code Playgroud)
因为我已经读过我们不应该增加/减少不指向序列或数组中元素的指针。
那么有人可以解释会发生什么以及我的示例是否正常(取消引用指针 p)?谢谢!
我知道这个问题过去已经被问过并得到了一些回答。
但是,我对尚未清除的细节(或者至少我找不到 QA)有疑问。
考虑以下代码:
T *mem = allocator_traits::allocate(allocator, 10);
allocator_traits::construct(allocator, mem+1, params...);
Run Code Online (Sandbox Code Playgroud)
mem[1]即使at的对象mem[0]还不存在,我也在构造一个对象。据我了解,指针算术在创建的非构造对象数组上定义得很好。但是,此QA 不回答此特定情况:
我应该说,当我说 storage + i 将在 P0593 下明确定义时,我假设元素 storage[0], storage[1], ..., storage[i-1] 已经被构造。尽管我不确定我对 P0593 的理解是否足够好,无法得出这样的结论,即它也不会涵盖尚未构建这些元素的情况。
换句话说,作者说这可能是UB。另一方面,它会使实现无法std::vector执行以下操作:
buf_end_size = newbuf + sizeof(T) * size();
Run Code Online (Sandbox Code Playgroud)
由于我希望它是有效的代码(并且我已经在某些实现中看到了这一点),这意味着指针算术对于i没有构造对象时的任何值也有很好的定义。
所以,我的问题是:这个 UB 还是我可以allocate在任何情况下安全地对返回的指针进行指针算术,例如,如果我想在位置 0 之前在位置 1 处构造元素?另外,答案在 C++17 和 C++20 之间有变化吗?
我知道指针算法不允许用于空指针。但想象一下我有这样的事情:
class MyArray {
int *arrayBegin; // pointer to the first array item, NULL for an empty array
unsigned arraySize; // size of the array, zero for an empty array
public:
int *begin() const { return arrayBegin; }
int *end() const { return arrayBegin + arraySize; } // possible? (arrayBegin may be null)
Run Code Online (Sandbox Code Playgroud)
是否有可能(允许)进行上述end()实现?或者是否有必要拥有:
int *end() const { return (arraySize == 0) ? nullptr : (arrayBegin + arraySize); }
Run Code Online (Sandbox Code Playgroud)
避免使用 nullptr 进行指针运算,因为arrayBegin空数组为 null(尽管arraySize在这种情况下也为零)?
我知道可以存储 …