标签: pointers

C多维数组中的指针地址

我正在搞乱多维数组和指针.我一直在看一个程序,它打印出一个简单数组的内容和地址.这是我的数组声明:

int zippo[4][2] = { {2,4},
            {6,8},
            {1,3},
            {5,7}   };
Run Code Online (Sandbox Code Playgroud)

我目前的理解是它zippo是一个指针,它可以保存其他几个指针的地址.默认情况下,zippo持有指针的地址zippo[0],也可以容纳指针的地址zippo[1],zippo[2]zippo[3].

现在,请采取以下声明:

printf("zippo[0] = %p\n", zippo[0]);
printf("  *zippo = %p\n", *zippo);
printf("   zippo = %p\n", zippo);
Run Code Online (Sandbox Code Playgroud)

在我的机器上,它提供以下输出:

zippo[0] = 0x7fff170e2230
  *zippo = 0x7fff170e2230
   zippo = 0x7fff170e2230
Run Code Online (Sandbox Code Playgroud)

我完全理解为什么zippo[0]*zippo拥有相同的价值.它们都是指针,它们都存储整数2的地址(默认),或者zippo[0][0].但是,zippo共享相同的内存地址又是什么呢?不zippo应该存储指针的地址zippo[0]?Whaaaat?

c memory arrays pointers multidimensional-array

28
推荐指数
3
解决办法
4万
查看次数

为什么不切换指针?

例如:

#include <stdio.h>

void why_cant_we_switch_him(void *ptr)
{
    switch (ptr) {
        case NULL:
            printf("NULL!\n");
            break;
        default:
            printf("%p!\n", ptr);
            break;
    }
}

int main(void)
{
    void *foo = "toast";
    why_cant_we_switch_him(foo);
    return 0;
}

gcc test.c -o test
test.c: In function 'why_cant_we_switch_him':
test.c:5: error: switch quantity not an integer
test.c:6: error: pointers are not permitted as case values
Run Code Online (Sandbox Code Playgroud)

只是好奇.这是技术限制吗?

编辑

人们似乎认为只有一个常量指针表达式.这是真的吗?举例来说,这里是在Objective-C(一种常见的范例是真的是仅含有C除了NSString,id并且nil,这仅仅是一个指针,所以它仍然是相关的-我只是想指出,有,事实上,一个共同的使用它,尽管这只是一个技术问题):

#include <stdio.h>
#include <Foundation/Foundation.h>

static NSString * const kMyConstantObject = @"Foo";

void why_cant_we_switch_him(id ptr) …
Run Code Online (Sandbox Code Playgroud)

c pointers switch-statement

28
推荐指数
6
解决办法
2万
查看次数

参考如何在内部实施?

只是想知道它是如何在不同的编译器和调试/发布配置中实现的.标准是否以某种方式提供有关其实施的建议?它在哪里有所不同?

我试图运行一个简单的程序,我已经从函数返回非const引用和指向局部变量的指针,但它的工作方式相同.那么内部引用只是一个指针是真的吗?

c++ pointers reference

28
推荐指数
4
解决办法
9380
查看次数

数组的地址

int t[10];

int * u = t;

cout << t << " " << &t << endl;

cout << u << " " << &u << endl;
Run Code Online (Sandbox Code Playgroud)

输出:

0045FB88 0045FB88
0045FB88 0045FB7C
Run Code Online (Sandbox Code Playgroud)

输出u是有道理的.

我理解t并且&t[0]应该具有相同的价值,但是怎么样&t也一样?实际意味着什么?

c++ arrays pointers memory-address

28
推荐指数
2
解决办法
2万
查看次数

为什么指向函数的指针大小与指向成员函数的指针大小不同?

指针只是一个地址吗?或者我错过了什么?

我测试了几种类型的指针:

  • 指向任何变量的指针是相同的(我平台上的8B)
  • 指向函数的指针大小相同,作为指向变量的指针(8B再次)
  • 指向具有不同参数的函数的指针 - 仍然相同(8B)

但是指向成员函数的指针更大 - 我的平台上有16B.

三件事:

  1. 为什么指向成员函数的指针更大?他们需要更多信息?
  2. 据我所知,标准只字未提指针的大小,除了void*必须能够"包含"任何指针类型.换句话说,任何指针必须能够被转换为void*,对吧?如果是这样,那么为什么sizeof( void* )是8,而sizeof指向成员函数的指针是16?
  3. 是否还有其他指针示例,它们具有不同的大小(我的意思是,对于标准平台,不是一些稀有和特殊的平台)?

c++ pointers member-function-pointers function-pointers

28
推荐指数
2
解决办法
6831
查看次数

正确销毁std :: map中的指针

我有一张地图宣称为

std::map<std::string, Texture*> textureMap;
Run Code Online (Sandbox Code Playgroud)

我用它来将纹理文件的路径与实际纹理配对,这样我就可以通过路径引用纹理,而不会为单个精灵加载相同的纹理.我不知道该怎么做才能正确销毁ResourceManager类(地图所在的)的析构函数中的纹理.

我想过使用像这样的迭代器的循环:

ResourceManager::~ResourceManager()
{
    for(std::map<std::string, Texture*>::iterator itr = textureMap.begin(); itr != textureMap.end(); itr++)
    {
        delete (*itr);
    }
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,它说删除预期指针.现在已经很晚了,所以我可能只是错过了一些明显的东西,但我想让它在睡前工作.所以我是关闭还是我完全朝着错误的方向?

c++ pointers destructor stl

28
推荐指数
2
解决办法
4万
查看次数

所有指针都是从指向结构类型的指针派生的吗?

问题

是否所有指针都是从指向结构类型的指针派生的问题都不容易回答.我发现这是一个重要问题,主要有以下两个原因.

A.缺少指向"任何"不完整或对象类型的指针,对方便的函数接口施加了限制,例如:

int allocate(ANY_TYPE  **p,
             size_t    s);

int main(void)
{
    int *p;
    int r = allocate(&p, sizeof *p);
}
Run Code Online (Sandbox Code Playgroud)

[ 完整代码示例 ]

指向"任何"不完整或对象类型的现有指针明确描述为:

C99/ C11 §6.3.2.3 p1:

指向void的指针可以转换为指向任何不完整或对象类型的指针.[...]

从指向"任何"不完整或对象类型的现有指针派生的指针,指向void的指针,严格地是指向void的指针,并且不需要使用从指向"任何"不完整的指针派生的指针进行转换或对象类型.


B.程序员根据他们对特定实现的经验,使用基于不需要的假设的约定,有意识地或不知不觉地与指针的泛化相关,这种情况并不少见.假设,例如可转换,可表示为整数或共享公共属性:对象大小,表示或对齐.


标准的话

根据C99 §6.2.5 p27/ C11 §6.2.5 p28:

[...]所有指向结构类型的指针应具有相同的表示和对齐要求.[...]

其次是C99 TC3 Footnote 39/ C11 Footnote 48:

相同的表示和对齐要求意味着可互换性作为函数的参数,函数的返回值和联合的成员.

虽然标准没有说:"指向结构类型的指针"并且选择了以下单词:"所有指向结构类型的指针",但它没有明确指定它是否适用于这种指针的递归推导.在标准中提到指针的特殊属性的其他情况下,它没有明确指定或提及递归指针派生,这意味着"类型派生"适用,或者它没有 - 但它没有明确提到.

虽然在引用类型时使用"所有指针"的措辞使用两次,(对于结构和联合类型),而不是更明确的措辞:在整个标准中使用的"指针",我们不能总结它是否适用于这种指针的递归推导.

c struct pointers c99 strict-aliasing

28
推荐指数
1
解决办法
812
查看次数

c中的数组名称究竟是什么?

我很难理解C中数组名称的类型和用法.这可能看起来很长,但请耐心等待.

我理解以下语句声明a是类型,int []整数数组.

int a[30];
Run Code Online (Sandbox Code Playgroud)

同时a也指出数组的第一个元素和类似*(a+2)的东西是有效的.因此,a看起来像一个指向整数指针.但实际上类型int []int*不同; 前者是数组类型,后来是指向整数指针.

类型int []变量int*在传递给函数时也会转换为类型变量; 因为C数组是通过引用传递的(sizeof运算符除外).

这就是让我垂涎的观点.看看下面这段代码:

int main()
{
    int (*p)[3];
    int a[3] = { 5, 4, 6 };

    p = &a;

    printf("a:%d\t&a:%d\n",a,&a);
    printf("%d",*(*p + 2));
}
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

a:2686720       &a:2686720
6
Run Code Online (Sandbox Code Playgroud)

那么,上面的代码是如何工作的呢?我有两个问题:

  1. a&a具有相同的值.为什么?
  2. 到底是int (*p)[3];做什么的?它声明了一个 …

c arrays pointers memory-address

28
推荐指数
2
解决办法
5750
查看次数

为什么我可以在使用双引号声明时将指针用作字符串,而不是在C中使用花括号?

如果我声明并使用这样的指针:

int counter;
char *pCow = "pCow goes MOO";

for(counter = 0; counter < 14; counter++)
    printf("%c", pCow[counter]);
Run Code Online (Sandbox Code Playgroud)

它显示整个字符串并且工作,是的,并且有很多欢乐.

但是,如果我使用这样的初始化器:

int counter;
char *pCow = {'p','C','o','w',' ','g','o','e','s',' ','M','O','O','\0'};

for(counter = 0; counter < 14; counter++)
    printf("%c", pCow[counter]);
Run Code Online (Sandbox Code Playgroud)

程序崩溃了,pCow拒绝为我的享乐主义乐趣而呻吟!

3 Warnings. 0 Errors
line 11 (near initialization for 'pCow') [enabled by default]   C/C++ Problem
line 11 excess elements in scalar initializer [enabled by default]  C/C++ Problem
line 11 initialization makes pointer from integer without a cast [enabled by default]   C/C++ Problem …
Run Code Online (Sandbox Code Playgroud)

c string pointers

28
推荐指数
2
解决办法
1413
查看次数

为什么直接使用条件运算符而不使用条件运算符进行分配时,该功能指针分配为何起作用?

(本示例中未使用#include,在带有g ++,选项-O0 -g3 -Wall -c -fmessage-length = 0的MacOS10.14,Eclipse IDE上编译)

假设此变量声明:

int (*fun)(int);
Run Code Online (Sandbox Code Playgroud)

无法使用“ std :: toupper和std :: tolower的无效重载”进行编译。

fun = (1 ? std::toupper : std::tolower);   // ERROR, invalid overload
Run Code Online (Sandbox Code Playgroud)

这样编译就可以了:

if (1) {
    fun = std::toupper;   // OK
}
else {
    fun = std::tolower;   // OK
}
Run Code Online (Sandbox Code Playgroud)

c++ pointers overloading function

28
推荐指数
2
解决办法
898
查看次数