有人可以告诉我之间的区别:
int *p;
p=(int*)malloc(10*sizeof(int));
free(p);
Run Code Online (Sandbox Code Playgroud)
要么
int *p;
p=(int*)malloc(10*sizeof(int));
p=NULL;
Run Code Online (Sandbox Code Playgroud) C中的以下声明:
int* a, b;
Run Code Online (Sandbox Code Playgroud)
将声明a为类型int*和b类型int.我很清楚这个陷阱,但我想知道的是它为什么会这样运作.为什么它不也宣布b作为int*,因为大多数人会直觉地想到?换句话说,为什么*适用于变量名,而不是类型?
当然你可以用这种方式写它,以便与它的实际工作方式更加一致:
int *a, b;
Run Code Online (Sandbox Code Playgroud)
但是,我和我所说过的每个人都用"指向int"的类型来思考,而不是指向某些数据的指针,而该数据的类型是"int".
这对C的设计者来说只是一个糟糕的决定还是有一些很好的理由为什么它会被这样解析?我确定之前已经回答了这个问题,但我似乎无法通过搜索找到它.
我很擅长使用C++,并且没有掌握语言的所有复杂性和细微之处.
在C++ 11中向任何类型的指针添加任意字节偏移量的最便携,正确和安全的方法是什么?
SomeType* ptr;
int offset = 12345 /* bytes */;
ptr = ptr + offset; // <--
Run Code Online (Sandbox Code Playgroud)
我在Stack Overflow和Google上找到了很多答案,但他们都提出了不同的建议.我遇到的一些变种:
ptr = (SomeType*)(((char*)ptr) + offset);
Run Code Online (Sandbox Code Playgroud)演员unsigned int:
ptr = (SomeType*)((unsigned int)ptr) + offset);
Run Code Online (Sandbox Code Playgroud)ptr = (SomeType*)((size_t)ptr) + offset);
Run Code Online (Sandbox Code Playgroud)"大小size_t并且ptrdiff_t总是与指针的大小一致.因此,这些类型应该用作大型数组的索引,用于存储指针和指针算术." - 关于 CodeProject上的size_t和ptrdiff_t
ptr = (SomeType*)((size_t)ptr + (ptrdiff_t)offset);
Run Code Online (Sandbox Code Playgroud)或者像之前的那样,但是intptr_t代替的size_t是签名而不是签名的:
ptr = (SomeType*)((intptr_t)ptr + (ptrdiff_t)offset);
Run Code Online (Sandbox Code Playgroud)仅转换为intptr_t,因为offset已经是有符号整数而intptr_t …
在我的代码中:
char *str[] = {"forgs", "do", "not", "die"};
printf("%d %d", sizeof(str), sizeof(str[0]));
Run Code Online (Sandbox Code Playgroud)
我得到了输出12 2,所以我怀疑是:
str和str[0]是字符指针,对不对?我想知道数组如何在c中工作.我最终得出一个假设,我想知道我是否正确.
我们知道数组是一系列相邻的内存盒(盒子),其中每个盒子的大小都是它所存储的类型(即如果INT的一个盒子的大小= sizeof(int),则一个3个INT的数组占用内存相邻的位置3 sizeof(int))
现在我们也知道我们可以为某种类型的数组动态分配内存(C中的malloc,C++中的new).
让我想知道的是,当使用括号[0]调用数组时,数组的第一个数据框的地址和第一个值(后面的框中的值)是数组[0] = =*(数组+ 0)==*数组(数组是否被声明为"type*array"或"type array []"或"type array [size]")和"数组"这样称为无论是定义为指针还是数组("type*array"或"type array []"或"type array [size]")是第一个框的地址.
我最后想到了,我想要对此进行确认:数组甚至用方括号([]声明)实际上在内存中是一系列n个指针,每个指针包含(具有不作为地址的值)的地址包含实际值的存储器盒Bi +那些包含实际值的存储器盒(B0,...,Bn).这样,当一个人声明"int array [5]"时,程序实际上分配了5个相邻的int指针框P0,P1,...,P4和5个整数计算机存储器B0,B1的内部存储器位置. ..,B4,其中Pi的值是Bi的地址

我是对还是错!! 谢谢!
我试图理解堆栈和堆内存之间的区别,这个问题在SO上以及这个解释做了很好的解释基础知识.
然而,在第二个解释中,我遇到了一个我有一个具体问题的例子,例子如下:

据说这个对象m是在堆上分配的,我只是想知道这是不是完整的故事.根据我的理解,对象本身确实在堆上分配,因为new关键字已用于其实例化.
但是,指向对象的指针m是不是在堆栈上分配的同一时间?否则,如何访问对象本身,当然它位于堆中.我觉得为了完整起见,本教程中应该提到这一点,留下它会给我带来一些混乱,所以我希望有人能够清楚地告诉我,我对我的理解是对的应该基本上有两个陈述,不得不说:
1. m已经在堆栈上分配了一个指向对象的指针
2.对象m本身(因此它携带的数据以及对其方法的访问)已在堆上分配
这是strtok()的解释.
#include <string.h>
char* strtok( char* s1,
const char* s2 );*
Run Code Online (Sandbox Code Playgroud)
第一次调用strtok()会返回指向s1指向的字符串中第一个标记的指针.对strtok()的后续调用必须将NULL指针作为第一个参数传递,以便获取字符串中的下一个标记.
但我不知道,为什么你必须传递NULL指针才能获得字符串中的下一个标记.我搜索了大约15分钟,但没有在互联网上找到解释.
考虑以下计划:
int main()
{
int array[9];
const int (*p2)[9] = &array;
}
Run Code Online (Sandbox Code Playgroud)
它在C++中编译得很好(请参见此处的实时演示),但在C中编译失败.默认情况下,GCC会发出以下警告.(见此处的现场演示).
prog.c: In function 'main':
prog.c:4:26: warning: initialization from incompatible pointer type [enabled by default]
const int (*p2)[9] = &array;
Run Code Online (Sandbox Code Playgroud)
但如果我使用-pedantic-errors选项:
gcc -Os -s -Wall -std=c11 -pedantic-errors -o constptr constptr.c
Run Code Online (Sandbox Code Playgroud)
它给了我以下编译器错误
constptr.c:4:26: error: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic]
Run Code Online (Sandbox Code Playgroud)
为什么它在C中编译失败而在C++中没有?C&C++标准对此有何看法?
如果我在数组声明语句中使用const限定符,它也可以在C中编译.那么,上面的程序中发生了什么?
((struct name*)0) - > member)在C中做什么?
我遇到的实际C语句是这样的:
(char *) &((struct name *)0)->member)
Run Code Online (Sandbox Code Playgroud)