错误1无法将类型'int **'隐式转换为'int *'。存在显式转换(您是否错过了演员?)

时间:2013-11-23 16:14:51

标签: c# pointers unsafe addressof

我正在学习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);
}

}

3 个答案:

答案 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;
        }
    }
}

}