我只是试图使用一个指向整数数组的void指针,我试着看看我是否可以通过将数组转换回int来打印它.但它给了我一些随机价值.你能告诉我哪里出错了吗?
#include<stdio.h>
#include<stdlib.h>
int main(){
int a[5];
int x;
int j;
a[0]=1;
a[1]=2;
a[2]=3;
a[3]=4;
void *arr=a;
for(j=0;j<4;j++){
x = *(int *)(arr+j);
printf("%d",x);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是这样的:
133554432131072512
Run Code Online (Sandbox Code Playgroud)
为什么它没有固定数组的元素a []即1,2,3,4?
我正在尝试一些非常简单的事情,应该很简单,但它不知何故让我感到烦恼......
我试图理解++对数组的影响,当被视为数组时被视为指针和指针.
所以,
int main()
{
int a[4] = { 1, 4, 7, 9 };
*a = 3;
*(a+1) = 4;
*++a = 4; //compiler error
}
Run Code Online (Sandbox Code Playgroud)
1:所以在*(a+1)=4我们设置[1] = 4; //快乐但是,当*++a = 4;我想要指针a增加一个因为++先于*然后*启动而我们使它等于4.但是这个代码不起作用......为什么会这样?
另一个问题:
int main()
{
int* p = (int *)malloc(8);
*p = 5;
printf("%d", p[0]);
*++p = 9; //now this works!
printf("%d", p[1]); //garbage
printf("%d", p[0]); //prints 9
}
Run Code Online (Sandbox Code Playgroud)
2:现在*++ p = 9; 工作得很好,但它的表现并不像数组.两个有什么不同?这只是递增p,并使其等于9.如果我打印p [0],它现在打印9,我看到虽然不能通过p [0]访问它,*(p-1)显示5还在那里.所以用[0]索引指针,它究竟指向哪里?发生了什么变化?
非常感谢所有专家!
LEA指令是否支持负位移?
mov rax, 1
lea rsi, [rsp - rax]
Run Code Online (Sandbox Code Playgroud)
当我在我的asm文件中使用上面的代码时,我得到了错误:
$ nasm -f macho64 test.asm
$ error: invalid effective address
Run Code Online (Sandbox Code Playgroud)
我知道我们可以在C中做这样的事情:
void foo(char *a, size_t b) {
*(a - b) = 1;
}
Run Code Online (Sandbox Code Playgroud)
那我假设:
lea rsi, [rsp - rax]
Run Code Online (Sandbox Code Playgroud)
将工作.
我还尝试使用以下命令查看GCC编译器的功能:
$ gcc -S foo.c // foo.c has the function foo(above) in it
Run Code Online (Sandbox Code Playgroud)
但是我的asm knowleage对我来说还不够理解GCC编译器的asm输出.
谁能解释原因:
lea rsi, [rsp - rax] ;; invalid effective address
Run Code Online (Sandbox Code Playgroud)
不起作用.我正在使用它们来实现同样的目标:
;; assume rax has some positive number
neg rax
lea rsi, [rsp + rax] …Run Code Online (Sandbox Code Playgroud) 我有一个代码,其中执行如下操作:
double computeSometing(const double * parameters)
{
return useValues(parameters - 10);
// in this special case, useValues only uses values that are
// at least at parameters[0] or after
}
Run Code Online (Sandbox Code Playgroud)
这看起来很糟糕,但是仅在以下情况下才调用此代码:在这种情况下,我知道useValues在10号之前不会使用任何值(情况并非总是如此),因此所使用的所有值都是“ inside” parameters。那是不确定的行为吗?我知道它只能在我使用过的所有编译器/平台上运行,但这并没有定义它。
我这样做是为了避免将其内容复制parameters到具有10个以上元素的新数组中,因为此函数对性能敏感。
受到我对最近帖子的评论的启发:C get element on place without parenthesis,我想知道以下代码是否违反了严格的别名规则:
#include <stdio.h>
int main(void)
{
int num[3] = { 1, 2, 3 };
printf("num[1] = %d\n", *(int *)((char *)num + sizeof(int)));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道将类型转换为其他类型的指针取消引用char是违规行为,但在这里,原始指针的类型为int *。它在被强制转换为char *then后被取消引用int *。
这是否违反了严格的别名规则?
在标准的指针算术规范中 ( [expr.add]/4.2,我们有:
否则,如果
P指向数组元素我的阵列对象的x与Ñ元素([dcl.array]),则表达式P + J和J + P(其中,J具有值Ĵ)点到(可能-假想)阵列元件I + J的x如果0 ? 我 + j ? n并且表达式P - J指向(可能是假设的)数组元素i ? Ĵ的x,如果0?一世 ?? 名词。
“可能-假设”在这里是什么意思?该段落已经将结果指针限制在数组范围内。好吧,包括最后一个插槽。它指的是这个吗?
我正在学习 C 编程,我在网上看到了本教程,其中指出您应该始终尽可能多地使用 [] 运算符而不是指针算法。
https://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html#dynamic
你可以使用指针算术(但一般不要)
考虑下面的 C 代码
int *p_array;
p_array = (int *)malloc(sizeof(int)*50);
for(i=0; i < 50; i++) {
p_array[i] = 0;
}
Run Code Online (Sandbox Code Playgroud)
使用如下代码的指针算术有什么区别(为什么不推荐)?
int *p_array;
p_array = (int *)malloc(sizeof(int)*50); // allocate 50 ints
int *dptr = p_array;
for(i=0; i < 50; i++) {
*dptr = 0;
dptr++;
}
Run Code Online (Sandbox Code Playgroud)
在哪些情况下使用指针算法会导致软件出现问题?这是不好的做法还是缺乏经验的工程师可能不注意?
在“使用 end()-- 迭代到 std::vector 的最后一个元素”的可接受答案中@barry 指出:
请注意,如果 vector::iterator 只是 T* (这将是有效的),则上面的第一种形式是错误的。无论如何,后两者都有效,因此更可取。
参考他的代码:
std::vector<int>::iterator it = --container.end();
std::vector<int>::iterator it = container.end() - 1;
std::vector<int>::iterator it = std::prev(container.end());
Run Code Online (Sandbox Code Playgroud)
这一观点在评论中存在争议,但没有明确的解决方案。这就是我的问题:第一个和第二个之间的语义差异究竟是什么?对于除 之外的结构上的迭代器,答案会有所不同吗vector?
常规静态分配数组如下所示,可以使用以下公式进行访问:
const int N = 3;
const int M = 3;
int a1[N][M] = { {0,1,2}, {3,4,5}, {6,7,8} };
int x = a1[1][2]; // x = 5
int y = *(a1+2+N*1); // y = 5, this is what [] operator is doing in the background
Run Code Online (Sandbox Code Playgroud)
数组是连续的内存区域。在动态数组分配的情况下看起来有所不同,而是有指向数组的指针数组:
int** a2 = new int*[N];
for (int i = 0; i < N; i++)
a2[i] = new int[M];
//Assignment of values as in previous example
int x = a2[1][2];
int y = *(*(a2+1))+2); // …Run Code Online (Sandbox Code Playgroud) c c++ pointer-arithmetic multidimensional-array implicit-conversion
我有以下 C++ 代码:
void bar(int&);
void baz();
void foo(std::vector<int>& v) {
int* pointer_to_last = v.data() + (v.size() - 1);
if (v.size() > 0 && *pointer_to_last == 42) {
bar(*pointer_to_last);
} else {
baz();
}
}
Run Code Online (Sandbox Code Playgroud)
我无条件创建一个指向向量最后一个元素的指针,但仅当向量不为空时才取消引用该指针。根据标准,这是否合法,或者上面的代码是否包含未定义的行为?
如果上面的程序合法,那么下面的程序也合法吗?
void bar(int&);
void baz();
void foo(std::vector<int>& v) {
int& reference_to_last = v.back();
if (v.size() > 0 && reference_to_last == 42) {
bar(reference_to_last);
} else {
baz();
}
}
Run Code Online (Sandbox Code Playgroud)
回调空容器会导致未定义的行为。
所以我假设这个程序不合法。是否有 GCC 或 Clang 的编译器标志或任何静态分析器可以对上述代码发出警告?
c++ pointers reference pointer-arithmetic undefined-behavior