我正在学习C和C#,这个问题适用于C#。我查看msdn上的指针并且此代码未编译,它给出错误:错误1无法将类型int**
隐式转换为int*
。存在显式转换(您是否错过了演员?)。我在这里缺少什么?
以下是代码:
int ix = 10;
unsafe
{
int* px1;
int* px2 = &ix; **The error is on this line**
}
编辑: 以下是该计划的全部内容:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management;
using System.Diagnostics;
using System.Windows.Forms;
using practice;
class Program
{
public delegate bool ThisIsTheDelegate(int number);
public delegate bool ThisIsAnotherDelegate(int number);
private static string address;
public static String Address
{
get
{
return address;
}
set
{
address = value;
}
}
static void Main()
{
int[] someArray = new int[] { 1, 2, 3, 5, 6, 7, 8, 9, 0 };
foreach (int number in someArray)
{
Console.WriteLine(number);
}
int integer = 98;
string someString = "edited";
string[] someStr = { "edited" };
String[] anotherStringSomestr = new String[] { "edited" };
var readWithLinq = from far in anotherStringSomestr
select far;
foreach (var some in readWithLinq)
{
Console.WriteLine(some);
}
Program newPro = new Program();
bool isEven1 = newPro.isEven(99);
Console.WriteLine(isEven1);
ThisIsTheDelegate newDelegate = newPro.isEven;
Console.WriteLine(newDelegate(98));
int[] numbers = { 1, 2, 3, 5, 6, 7, 8, 9 };
List<int> evenNumbers = FilterArray(numbers, newDelegate);
foreach(int integer1 in evenNumbers)
{
Console.WriteLine(integer1);
}
List<int> oddNumbers = FilterArray(numbers, isOdd);
foreach (int integer1 in oddNumbers)
{
Console.WriteLine(integer1);
}
ThisIsAnotherDelegate anotherDelegate;
anotherDelegate = number => (number % 2 == 0);
Console.WriteLine("{0} is a even number", anotherDelegate(4));
for (int i = 0; i < someString.Length; i++)
{
Console.WriteLine(someString);
}
for (int i = 0; i < someStr.Length; i++)
{
Console.WriteLine(someStr[i]);
}
Console.WriteLine(integer);
SimpleStruct structss = new SimpleStruct();
structss.DisplayX();
M.x = 1;
structss.x = 98;
Console.WriteLine(M.x);
Console.WriteLine(structss.x);
M.structtaker(ref structss);
M.classtaker();
Console.WriteLine(structss.x);
Console.WriteLine(M.x);
M.x = 1;
structss.x = 98;
int ix = 10;
unsafe
{
int* px1;
int* px2 = &ix;
}
int selection = 98;
while (selection != 0)
{
mainMenu();
Console.Write("Enter choice: ");
selection = Convert.ToInt32(Console.ReadLine());
switch (selection)
{
case 0:
break;
case 1:
openSomething();
break;
case 2:
calculator();
break;
case 3:
coolestProgramEverALive();
break;
case 4:
make_to_do_list();
break;
case 5:
add_to_do_list();
break;
case 6:
readToDoList();
break;
case 7:
linq_and_arrays();
break;
case 8:
calendar();
break;
case 9:
linq_and_collections();
break;
default:
Console.WriteLine("Unkown selection. Try again");
break;
}
}
}
private static bool isOdd(int number)
{
return (number % 2 == 1);
}
private static List<int> FilterArray(int[] numbers, ThisIsTheDelegate newDelegate)
{
List<int> result = new List<int>();
foreach (int item in numbers)
{
if (newDelegate(item))
result.Add(item);
}
return result;
}
private static void linq_and_collections()
{
List<string> names = new List<string>();
names.Add("Billy");
names.Add("Steve");
names.Add("Casandra");
names.Insert(0, "Johanna");
names.Add("Sonny");
names.Add("Suzanne");
names.Insert(2, "Sid");
var queryLinqUpper = from name in names
where (name.StartsWith("S") || name.StartsWith("B") || name.StartsWith("J"))
let namesToUpper = name.ToUpper()
orderby namesToUpper
select namesToUpper;
foreach (var linqToUpper in queryLinqUpper)
{
Console.Write(linqToUpper + " ");
}
Console.WriteLine();
M.WriteTextToConsole("Hello, world. Programming in C# is fun");
char c = 'A';
int count = 14;
String str = new String(c, count);
str.WriteTextToConsole();
M.WriteTextToConsole(str);
}
private static void calendar()
{
Application.Run(new Form1());
}
private static void readToDoList()
{
var files = from file in Directory.GetFiles(@"C:\data", "*.txt")
select file;
int number = 1;
foreach (var file in files)
{
Console.WriteLine(number + ". " + file);
number++;
}
Console.Write("What todolist do you want to read? Give me the name:");
try
{
string name = Console.ReadLine();
Address = Path.Combine(@"C:\data", name + ".txt");
TextReader inFile = new StreamReader(Address);
while (inFile.Peek() != -1)
{
string line = inFile.ReadLine();
Console.WriteLine(line);
}
inFile.Close();
}
catch (Exception ex)
{
MessageBox.Show("Exception thrown!", "Error");
Console.WriteLine(ex.ToString());
}
}
private static void linq_and_arrays()
{
int numberOfElements;
Console.WriteLine("Start by setting the int[] array.");
Console.Write("How many elements are there in your array?");
numberOfElements = Convert.ToInt32(Console.ReadLine());
int[] array = new int[numberOfElements];
for (int i = 0, j = numberOfElements; i < numberOfElements; i++, j--)
{
Console.Write("Integers left to add {0}. Enter an integer:", j);
array[i] = Convert.ToInt32(Console.ReadLine());
}
var arrayquery = from value in array
select value;
foreach (var val in arrayquery)
{
Console.WriteLine("Value from array:{0}", val);
}
}
private static void add_to_do_list()
{
Console.WriteLine("Which todolist do you want to modify?");
listToDoLists();
Console.Write("Enter name of todolist: ");
string name = Console.ReadLine();
Address = Path.Combine(@"C:\data", name + ".txt");
String tempString;
StreamWriter stream;
stream = File.AppendText(Address);
Console.Write("Enter your new ToDo: ");
tempString = Console.ReadLine();
stream.WriteLine(tempString);
stream.Close();
TextReader inFile;
inFile = new StreamReader(Address);
while (inFile.Peek() != -1)
{
string line = inFile.ReadLine();
Console.WriteLine(line);
}
inFile.Close();
}
private static void listToDoLists()
{
int filenumber = 1;
string[] filepaths = Directory.GetFiles("C:\\data\\", "*.txt");
foreach (string file in filepaths)
{
Console.WriteLine(filenumber + ". " + file);
filenumber++;
}
}
private static void make_to_do_list()
{
string path, name;
string yesOrNo;
Console.Write("Enter name of todolist: ");
name = Console.ReadLine();
path = Path.Combine(@"C:\data", name + ".txt");
TextWriter outFile = new StreamWriter(path);
labelOne: // else clause : unknown answer
Console.WriteLine("Do you want to add something to todolist.Y/N?");
yesOrNo = Console.ReadLine();
if (yesOrNo.ToLower() == "y")
{
string line;
int lines;
Console.Write("How many lines?");
lines = Convert.ToInt32(Console.ReadLine());
for (int i = 0; i < lines; i++)
{
Console.Write("Enter a line of text: ");
line = Console.ReadLine();
outFile.WriteLine(line);
}
outFile.Close();
}
else if (yesOrNo.ToLower() == "n")
{
Console.WriteLine("You can close the application now.");
}
else
{
Console.WriteLine("Unknown answer. Try again");
goto labelOne;
}
}
private static void coolestProgramEverALive()
{
System.Diagnostics.Process.Start(@"C:\Users\KristjanBEstur\Documents\Visual Studio 2012\Projects\The_coolest_program_ever_alive\The_coolest_program_ever_alive\obj\Debug\The_coolest_program_ever_alive.exe");
}
private static void calculator()
{
System.Diagnostics.Process.Start("calc");
}
private static void openSomething()
{
System.Diagnostics.Process.Start("notepad");
}
private static void mainMenu()
{
Console.WriteLine("Main Menu");
Console.WriteLine("0. Quit");
Console.WriteLine("1. OpenSomething");
Console.WriteLine("2. Calculator");
Console.WriteLine("3. coolestProgramEverAlive");
Console.WriteLine("4. Make todolist");
Console.WriteLine("5. Add to todolist");
Console.WriteLine("6. Read to do list");
Console.WriteLine("7. Linq and arrays");
Console.WriteLine("8. Calendar");
Console.WriteLine("9. Linq and collections");
}
public bool isEven(int number)
{
return (number % 2 == 0);
}
}
static class M
{
public static int x;
public static void WriteTextToConsole(this string text)
{
Console.WriteLine(text);
}
public static void structtaker(ref SimpleStruct s)
{
s.x = 5;
}
public static void classtaker()
{
M.x = 5;
}
}
class Test
{
static int value = 20;
unsafe static void F(out int* pi1, ref int* pi2) {
int i = 10;
pi1 = &i;
fixed (int* pj = &value) {
// ...
pi2 = pj;
}
}
}
struct SimpleStruct
{
public int x;
private int xval;
public int X
{
get
{
return xval;
}
set
{
if (value < 100)
xval = value;
}
}
public void DisplayX()
{
Console.WriteLine("The stored value is: {0}", X);
}
}
答案 0 :(得分:2)
我希望我能复制一下,这似乎是一个相当有趣的问题。以下是我认为适用于此的标准部分(抱歉格式化):
18.3固定和可移动变量运算符地址(第18.5.4节)和固定语句(第18.6节)将变量分为两类: 固定变量和可移动变量。固定变量驻留在 不受垃圾操作影响的存储位置 集电极。 (固定变量的例子包括局部变量,值 参数和通过解除引用指针创建的变量。)在 另一方面,可移动变量驻留在存储位置 受垃圾收集者搬迁或处置。 (例子 可移动变量包括对象和元素中的字段 数组。)&amp;运算符(第18.5.4节)允许固定地址 变量无限制地获得。但是,因为一个 可移动变量可由垃圾重新安置或处置 收集器,只能获得可移动变量的地址 使用固定语句(第18.6节),该地址仅保持有效 在固定的声明期间。准确地说,一个固定的 变量是以下之一:•由a产生的变量 简单名称(第7.6.2节),引用局部变量或值 参数,除非该变量由匿名函数捕获。 •由V.I形式的成员访问(第7.6.4节)产生的变量, 其中V是结构类型的固定变量。 •产生的变量 来自* P,a形式的指针 - 间接表达式(第18.5.1节) 形式为P-> I的指针成员访问(第18.5.2节)或a 形式为P [E]的指针元素访问(第18.5.3节)。所有其他变量 被归类为可动变量。请注意,静态字段是 归类为可移动变量。另请注意,参考或退出 参数被分类为可移动变量,即使参数也是如此 给定的参数是固定变量。最后,注意一个 通过解除引用指针生成的变量始终归类为a 固定变量。
我花了一些时间试图创建一个类似的错误,但不是。我能够重新创建问题的唯一方法是使用以下代码:
void test() {
int ix = 10;
unsafe {
int* px1 = &ix;
int* px2 = &px1; // **The error is on this line**
}
}
当然,通过将ix声明移动到安全范围内,无法修复此代码。也许您可以尝试在一小段代码(如上所述)中复制原始问题,并验证问题和修复程序是否都会复制。也许VS变得困惑。我遇到了没有任何意义的问题,并且通过退出VS并重新启动(不经常但几次)而离开了。
答案 1 :(得分:0)
我将i声明移到了不安全的区域内并修复了它,我不知道为什么?
以下是代码:
unsafe
{
int ix = 10;
int* px1;
int* px2 = &ix;
}
答案 2 :(得分:0)
我已经移动了表达式“int i = 10;”走出不安全的区块,现在它编译。我还将代码置于另一个vs2012pro实例的新项目中。这也编译。所以现在我无法复制错误。
以下是代码:
int ix = 10;
unsafe
{
int* px1;
int* px2 = &ix;
Test.F(out px1, ref px2);
Console.WriteLine("*px1 = {0}, *px2 = {1}",
*px1, *px2); // undefined behavior
}
这是另一个项目:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace saxerium
{
class Program
{
static void Main(string[] args)
{
int ix = 10;
unsafe
{
int* px1;
int* px2 = &ix;
Test.F(out px1, ref px2);
Console.WriteLine("*px1 = {0}, *px2 = {1}",
*px1, *px2); // undefined behavior
}
}
}
class Test
{
static int value = 20;
public unsafe static void F(out int* pi1, ref int* pi2)
{
int i = 10;
pi1 = &i;
fixed (int* pj = &value)
{
// ...
pi2 = pj;
}
}
}
}