gpt4 book ai didi

c++ - C和C++的指针区别

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:11:19 25 4
gpt4 key购买 nike

我注意到以下 C 代码给出“警告:初始化丢弃指针目标类型的限定符”,但它仍然可以编译并按预期运行(输出“W”字符)。

#include <stdio.h>
int main(int argc, char *argv[])
{
char buffer[20] = {'H','e','l','l','o',' ','W','o','r','l','d','!','\0'};

const char* p = &buffer[0];

char* c = (p + 6);

printf("%c\n",*c);
}

在 C++ 中,相当相似的代码根本无法编译,并提示“错误:从‘const char*’到‘char*’的无效转换”

#include <iostream>
using namespace std;
int main()
{
char buffer[20] = {'H','e','l','l','o',' ','W','o','r','l','d','!','\0'};

const char* p = &buffer[0];

char* c = p + 6;

cout << *c;
cout << endl;
return 0;
}

这是什么原因?

是否可以修复 C++ 代码,使其像对应的 C 代码一样编译(和运行)?

更好的解释:感谢您的所有回答,但大多数人没有理解我真正的问题,所以我会尝试更详细地解释。

我正在使用用 C 编写的库。 header 中的函数原型(prototype)类似于:

void parse (const char* p, uint16_t len, uint8_t is_eof);

在这个函数的实现中,恰好运行了如下代码

char* c = p + 6;

如果我用 C 编写代码并针对该库进行编译,一切都很好。

现在我想在 C++ 中移植这个库,因为我在 C++ 项目中需要它。通过将函数参数重新定义为变量而不是常量,我成功地移植了库。但由于 p 指针实际上不需要更改,所以我更愿意将其定义为常量,就像在原始 C 库中一样。放置一个变量而不是一个常量我最终移植了一个库而不保留所有原始语义。这很糟糕,因为我不知道 C++ 库是否像原始 C 库一样运行。

我希望这已经足够清楚了。

一个(希望)更好的解释:

我正在学习 AVR Tutorials - [CODE][C] Parsing strings flexibly/efficiently with Ragel 中的教程该问题与 parse_microscript() 函数有关。

因为我想在解析器中嵌入 Arduino 代码(即 Serial.println();),所以我尝试用 C++ 宿主语言编译这个 Ragel 解析器,而不是比教程中建议的 C。

首先,我尝试在生成的 C 代码中包含 Arduino.h,但是 Arduino IDE不会编译(我相信是因为混合了 C 和 C++ 代码)。

然后我尝试从同一个 Ragel 脚本生成 C++ 代码,但是在编译多个“从‘const char*’到‘char*’的无效转换”错误时,目标是生成的代码。

让它在 C++ 中工作的唯一方法是删除所有常量关键字。这很糟糕,因为我正在更改 C 代码的原始语义,但它有效。

我试图通过提供上述 C 和 C++ 片段来隔离问题,但我可能没有很好地解释这一点。

公认的答案是让 C++ 片段编译的原因,但是当我在 Arduino 代码中尝试这个解决方案时,它不起作用。

我将使用命令 ragel -G2 -o microscript.cpp microscript.rl 编译的工作 Ragel 脚本:

#include "qp_port.h"
#include "pelican.h"
#include "bsp.h"
#include "Arduino.h"

static uint16_t currentNumber;

%%{
machine microscript;

action ClearNumber {
currentNumber = 0;
}

action PrintNumber {
Serial.print("parameter: ");
Serial.println(currentNumber);
}

action RecordDigit {
uint8_t digit = (*p) - '0';
currentNumber = (currentNumber * 10) + digit;
}

number = ((digit @RecordDigit)+) > ClearNumber % PrintNumber;
whitespace = space+;

numlist = number (',' number)*;

crlf = '\r\n';

OK = crlf 'OK' crlf;

main := |*

crlf => {Serial.println("crlf");};

OK => {Serial.println("OK detected");};

*|;
}%%

%% Write data;

static uint8_t cs; /* The current parser state */
static char* ts;
static char* te;
static char* act;


void init_microscript() {
%% write init;
}

void parse_microscript(char* p, uint16_t len, uint8_t is_eof) {
char* pe = p + len; /* pe points to 1 byte beyond the end of this block of data */
char* eof = is_eof ? pe : ((char*) 0); /* Indicates the end of all data, 0 if not in this block */

%% write exec;
}

如您所见,我不得不将 parse_microscript 函数的第一个参数从 const char* p 更改为 char*p , 和 const char* pechar* pe

最佳答案

您可以通过使用正确的类型来修复两者:

const char* c = p + 6;

关于c++ - C和C++的指针区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13765898/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com