有没有什么好的理由(除了"宏是邪恶的",也许)不使用以下宏?
#define DELETE( ptr ) \
if (ptr != NULL) \
{ \
delete ptr; \
ptr = NULL; \
}
#define DELETE_TABLE( ptr ) \
if (ptr != NULL) \
{ \
delete[] ptr; \
ptr = NULL; \
}
Run Code Online (Sandbox Code Playgroud) 我有以下结构:
typedef struct{
int vin;
char* make;
char* model;
int year;
double fee;
}car;
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个类型为car的指针
car *tempCar;
Run Code Online (Sandbox Code Playgroud)
如何为tempCar分配值?我遇到了麻烦
tempCar.vin = 1234;
tempCar.make = "GM";
tempCar.year = 1999;
tempCar.fee = 20.5;
Run Code Online (Sandbox Code Playgroud)
编译器一直说tempCar是car*类型.我不确定我做错了什么
可能重复:
为什么你想要在堆而不是堆栈上分配内存?
Test2 *t2 = new Test2();
t2->test();
Test2 t3;
t3.test();
Run Code Online (Sandbox Code Playgroud)
为什么我要创建Test2类型的指针对象?为什么不做Test2的非指针版本?我为什么要做指针对象?
在这里找到答案:
根据C++标准(3.7.3.2/4)使用(不仅是解除引用,还有复制,转换,其他任何),无效指针是未定义的行为(如果有疑问也会看到这个问题).现在,遍历STL容器的典型代码如下所示:
std::vector<int> toTraverse;
//populate the vector
for( std::vector<int>::iterator it = toTraverse.begin(); it != toTraverse.end(); ++it ) {
//process( *it );
}
Run Code Online (Sandbox Code Playgroud)
std::vector::end()是超出容器最后一个元素的假设元素的迭代器.那里没有元素,因此使用指针通过迭代器是未定义的行为.
那么!= end()工作怎么样呢?我的意思是为了进行比较,需要构造迭代器包装无效地址,然后必须在比较中使用该无效地址,这也是未定义的行为.这样的比较合法吗?为什么?
在另一个问题的热门评论主题之后,我开始讨论C99标准中有关C数组的内容和内容.
基本上,当我定义一个2D数组时int a[5][5],标准C99是否保证它将是一个连续的整数块,我可以将它投射到(int *)a并确保我将拥有一个25个整数的有效一维数组.
正如我理解标准的那样,上面的属性隐含在sizeof定义和指针算术中,但其他人似乎不同意并且说铸造到(int*)上面的结构给出了一个未定义的行为(即使他们同意所有现有的实现实际分配连续的价值观).
更具体地说,如果我们认为一种实现可以检测数组检查所有维度的数组边界并在访问1D数组时返回某种错误,或者不能正确访问第1行以上的元素.这样的实施可以是标准的编制吗?在这种情况下,C99标准的哪些部分是相关的.
我有一个返回地址的函数如下
struct node *create_node(int data)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->data=data;
temp->next=NULL;
printf("create node temp->data=%d\n",temp->data);
return temp;
}
Run Code Online (Sandbox Code Playgroud)
struct node是哪里的
struct node {
int data;
struct node *next;
};
Run Code Online (Sandbox Code Playgroud)
如何在printf("")中查看存储在temp中的地址?
更新
如果我检查gdb中的地址,地址将以十六进制数格式显示,即0x602010,其中相同的地址printf("%p",temp)输入不同的数字,这与我在gdb打印命令中看到的不同.
我有一个程序可以接受命令行参数,我想从一个函数访问用户输入的参数.如何传递的*argv[],从int main( int argc, char *argv[])那个函数?我对指针的概念不熟悉,*argv[]看起来有点过于复杂,我无法自己解决这个问题.
我的想法是main通过将我想要对参数执行的所有工作移动到库文件来尽可能保持干净.当我设法把它们拿到外面时,我已经知道我要对这些论点做些什么main.我只是不知道如何让他们到那里.
我正在使用GCC.提前致谢.
如今,使用C++ 11,Whats建议使用,Zero还是NULL?第二个如果?
int * p = getPointer();
if( 0 == p ){
// something
}
if( NULL == p ){
// something
}
Run Code Online (Sandbox Code Playgroud)
更新:我忘了新的
if( nullptr == p ){
// something
}
Run Code Online (Sandbox Code Playgroud)
更新2:示例是显示写入空指针的选项,我知道编写起来比较愉快if( !p ).
在PJ Plauger的书"标准C库"中,他警告将函数指针赋给NULL.
具体来说,他说:
宏NULL 用作几乎通用的空指针常量.您将它用作数据对象指针的值,该指针应指向程序中未声明(或分配)的数据对象.正如我在第216页提到的,宏可以具有以下任何定义0,0L或(void*)0.
最后一个定义与任何数据对象指针兼容.但是,它与函数指针不兼容.这意味着你不能写
int (*pfun) (void) = NULL; /* WRONG */翻译者可能会抱怨表达式类型与您要初始化的数据对象不兼容.
他继续说:
但是,无法保证指向void的指针与任何其他(非字符)指针具有相同的表示形式.它甚至不与函数指针兼容.这意味着您不能将NULL写为通用空指针常量.你也不能安全地将它用作参数表达式来代替任意数据对象指针.
我已经将函数指针分配NULL了很长一段时间没有任何问题,我想知道它是否不可移植.
特别:
void (*test)() = NULL =>用gcc和g ++编译好
void (*test)() = 0 =>用gcc和g ++编译好
void (*test)() = (void*)0 =>在gcc和g ++中都产生了无效的转换错误
编辑:void (*test)() = (void*)0在gcc中编译很好,我使用的文件扩展名为.cpp ...尽管Plauger说分配函数指针NULL是错误的,它仍然会编译吗?
我不明白的部分是我的stddef.h中NULL的定义:
#if defined (_STDDEF_H) || defined (__need_NULL)
#undef NULL /* in case <stdio.h> has defined it. */
#ifdef __GNUG__
#define NULL __null
#else …Run Code Online (Sandbox Code Playgroud) 我是一个C++菜鸟,我很确定这是一个愚蠢的问题,但我不太明白为什么从以下代码出现错误(不会出现):
#include <iostream>
using namespace std;
int main()
{
int a,*test;
*test = &a; // this error is clear to me, since an address cannot be
// asigned to an integer
*(test = &a); // this works, which is also clear
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但为什么这也有效呢?
#include <iostream>
using namespace std;
int main()
{
int a, *test= &a; // Why no error here?, is this to be read as:
// *(test=&a),too? If this is the case, why is the
// priority …Run Code Online (Sandbox Code Playgroud)