有人可以解释为什么在输出中3 4 4打印而不是打印吗4 4 4?
#include <stdio.h>
int main(){
int a[] ={0,1,2,3,4};
int *p[] = {a,a+1,a+2,a+3,a+4};
int **ptr= p;
ptr++;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
*ptr++;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
*++ptr;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
++*ptr;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)

测试平台是Linux 32位.
我在代码中发现了一个错误,我不知道为什么......
我简化了这段代码并把它放在这里:
unsigned int aa = 0;
unsigned int array[10000];
unsigned int* ptr = array + 2000;
printf("aa: %d ", aa); // value 1
printf("ptr: %d \n", ptr); //value 2
printf("aa+ptr: %d \n", aa + ptr); // value 3
Run Code Online (Sandbox Code Playgroud)
编译器是gcc版本4.6.3
这看起来很傻但我不明白为什么value3!= value1 + value2
谁能给我一些帮助?
谢谢!
我有一个处理类似C的字符串的例程,导致通常的Delphi字符串:
class function UTIL.ProcessString(const S: string): string;
var
SB:TStringBuilder;
P:MarshaledString;
procedure DoIt(const S:string;const I:Integer=2);
begin
SB.Append(S);
Inc(P,I);
end;
begin
SB:=TStringBuilder.Create;
P:=PChar(S);
while P<>nil do
begin
if P^<>'\' then DoIt(P^,1) else
case (P+1)^ of
'\','"':DoIt((P+1)^);
#0,'n':DoIt(sLineBreak);
't':DoIt(#9);
else DoIt('\'+(P+1)^,2);
end;
end;
Result:=SB.ToString;
SB.Free;
end;
Run Code Online (Sandbox Code Playgroud)
问题是循环从不退出.调试显示该行while P<>nil do未评估为False,因为在处理结束时P为'',因此代码尝试对其执行超范围操作.由于我没有在Delphi中找到关于指针数学的任何简明文档,所以我很可能在这里有错.
编辑:我已经重写了这个功能,所有内容都是这样读的:
class function UTIL.ProcessString(const S: string): string;
var
SB:TStringBuilder;
P:PChar;
C:Char;
begin
SB:=TStringBuilder.Create;
P:=PChar(S);
repeat
C:=P^;
Inc(P);
case C of
#0:;
'\':
begin
C:=P^;
Inc(P);
case C of
#0,'n':SB.Append(sLineBreak);
'\','"':SB.Append(C);
't':SB.Append(#9);
else …Run Code Online (Sandbox Code Playgroud) 我需要帮助理解如何在C中使用点算法来计算二维数组.我正在使用这个网站(http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/)作为参考(使用示例1) ,一个指针).
int numRows = 2;
int numColumns = 3;
double * arrayMatrix = malloc(numRows * numColumns * sizeof(double));
int row = 0;
int column = 0;
printf("\nPlease enter the elements of your augmented matrix:\n");
for(row = 0; row < numRows; row++)
{
for(column = 0; column < numColumns; column++)
{
printf("A[%d][%d]:", row + 1, column + 1);
scanf("%lf", &arrayElement);
printf("\n");
*(arrayMatrix + row * numColumns + column) = arrayElement;
//arrayMatrix[row + numColumns + column] = arrayElement;
} …Run Code Online (Sandbox Code Playgroud) 我需要一个函数来)从字符串的末尾删除字符.例如,hello,world)应该转换为hello,world.
我写了这个:
char *a="hello,world)";
int a_len=strlen(a);
*(a+a_len-1)='\0';
printf("%s", a);
Run Code Online (Sandbox Code Playgroud)
但输出中没有显示任何内容.
我的开发环境包含用于ARM OMAP Sitata的g ++交叉编译器.当向unsigned int*添加unsigned int时,我发现了一个简单的指针算法的不寻常的细微差别,如下所示:
unsigned int* dst_base_addr;
unsigned int* dst_addr;
unsigned int dst_offset;
Run Code Online (Sandbox Code Playgroud)
只是尝试将(unsigned int)添加到(unsigned int*)
dst_addr = dst_base_addr + dst_offset;
Run Code Online (Sandbox Code Playgroud)
上述内容并未被解释为人们可能会天真地想到,但实际上会产生以下等效结果
dst_addr = (unsigned int*)((unsigned int)dst_base_addr + (dst_offset << 2));
Run Code Online (Sandbox Code Playgroud)
补救当然是按照以下方式进行适当的类型转换
dst_addr = (unsigned int*)((unsigned int)dst_base_addr + dst_offset);
Run Code Online (Sandbox Code Playgroud)
问题:为什么在这种情况下甚至需要正确的类型转换?
是((char *)NULL - (char *)NULL)UB吗?
海事组织的答案在这里不是微不足道的。有什么想法吗?
Godbolt 实验链接https://godbolt.org/z/zgVGk9
我不是在问添加一些空指针的东西(就像在提议的欺骗中一样),而只是关于一种特殊情况。
我已经看到结构的第一个地址同时是该结构的第一个成员的第一个地址。现在我想了解的是,为什么我总是需要双指针在结构中移动:
#include <stdio.h>
#include <stdlib.h>
struct foo
{
char *s;
char *q;
};
int main()
{
struct foo *p = malloc(sizeof(struct foo));
char ar[] = "abcd\n";
char ar2[] = "efgh\n";
*(char**)p = ar;
*(char**)((char**)p+1) = ar2; //here pointer arithmetic (char**)p+1
printf("%s\n",p->q);
}
Run Code Online (Sandbox Code Playgroud)
问题是,为什么我需要char**而不是 simple char*?我在汇编程序中看到的是在简单的情况下char*,算术会表现得像正常一样char。也就是说 -> 的表达式(char*)p+1会将地址p仅移动一个字节(而不是8地址为 8 个字节长)。但是类型char* 是地址,所以我不明白为什么算术的行为类似于取消引用类型(纯字符 -> 一个字节)。
所以对我来说唯一的解决方案是添加另一个间接char**,其中指针算术神奇地8作为大小。那么为什么在结构中需要这种奇怪的转换呢?
我正在寻找一种在数组中找到给定 int 的方法,我找到了这个解决方案
#include <algorithm>
#include <iostream>
using namespace std;
int main() {
int data[] = {23, 45, 56, 12, 34, 56};
int target = 56;
int arraySize = sizeof(data) / sizeof(*data);
bool isPresent = std::find(data, data + arraySize, target) != data + arraySize;
if (isPresent) {
cout << "The element is present";
} else {
cout << "The element is not present";
}
return 0;
Run Code Online (Sandbox Code Playgroud)
现在我测试了并且它有效,但我想知道为什么在 find() 之后有这个 != data + arraySize ?希望得到解释
我想做以下事情:
char c[] = "programming";
char *p;
*(c-1)='l';
*(c-2)='l';
*(c-3)='l';
*(c-4)='l';
*(c-5)='l';
p=&c[0];
cout<<*(c-1);
Run Code Online (Sandbox Code Playgroud)
l只有在我省略了p=&c[0];为什么会这样打印时才打印?有显然是没有关系p和c.
除了能够解除引用之外void**,我不理解以下内容:
void * foo, **bar;
foo++;//error
bar++;//no error
Run Code Online (Sandbox Code Playgroud)
为什么不是第一次工作而第二次工作呢?有什么不同?
我在指针算术中发现了一种非常有趣的现象.我正在使用microsoft visual studio 2015
我有以下程序
#include<iostream>
using namespace std;
void testFunction2(const char *s, int n)
{
unsigned int x;
for (x = n - 1; x >= 0; --x)
cout << *(s + x);
}
int main()
{
char str[80] = "string";
testFunction2(s, strlen(s));
}
Run Code Online (Sandbox Code Playgroud)
预计会str预留打印,即.然而,gnirts打印出无尽的Mojibake并且警报开启.
但是,如果我将for循环中的第二个条件从
x>=0更改为x>=1.正如预期的那样,它将打印"gnirt".
我也尝试过代码cout<<*(str+0);,它会打印出第一个字符str,如预期的那样.
结果自相矛盾.问题是什么?我还想知道这个问题是否在visual studio中独一无二?