小编she*_*lbc的帖子

指针作为C中的函数参数

如果我有这个代码,例如:

int num = 5;
int *ptr = #
Run Code Online (Sandbox Code Playgroud)

以下两个功能有什么区别?

void func(int **foo);
void func(int *foo); 
Run Code Online (Sandbox Code Playgroud)

我在哪里调用函数:

func(&ptr); 
Run Code Online (Sandbox Code Playgroud)

我意识到前两者采用指针作为参数指针,而第二种只采用指针.

如果我传入func(&ptr),我实际上是在传入一个指针.指针指向另一个指针有什么区别?

我相信后者会给出一个不兼容的警告,但只要你知道你在做什么,似乎细节无关紧要.似乎可能为了可读性和理解,前者是更好的选择(2星指针),但从逻辑的角度来看,有什么区别?

c parameters pointers parameter-passing

27
推荐指数
3
解决办法
5万
查看次数

由于未定义的引用,无法让OpenCV编译?

代码很简单,教程基本上是直接的.我正在运行Arch Linux并且存储了OpenCV库/usr/include/.我也检查过以确保它/usr/include在我的PATH中.

#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <iostream>

using namespace cv; 

int main(int argc, char** argv){
    Mat image;
    Mat grayImage; 

    if(!argv[1]){
        std::cerr << "No image data!" << std::endl;
        return -1; 
    }

    image = imread(argv[1], 1);
    cvtColor(image, grayImage, CV_BGR2GRAY);
    imwrite("Gray_Image.jpg", grayImage);

    namedWindow(argv[1], CV_WINDOW_AUTOSIZE);
    namedWindow("Gray Image", CV_WINDOW_AUTOSIZE);

    imshow(argv[1], image);
    imshow("Gray Image", grayImage);

    waitKey(0);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器进程成功查找并包含这些头文件,但我仍然在编译时得到未定义的引用错误.如果你查看我包含的头文件,他们还包括其他文件/usr/include/opencv2.我检查过,这样的头文件确实存在.

有任何想法吗?

/tmp/ccudBcqD.o: In function `main':
test.cpp:(.text+0xc0): undefined reference to `cv::imread(std::string const&, int)'
test.cpp:(.text+0x11f): undefined reference to `cv::_OutputArray::_OutputArray(cv::Mat&)' …
Run Code Online (Sandbox Code Playgroud)

c++ opencv archlinux

27
推荐指数
3
解决办法
9万
查看次数

使用IntelliJ IDE自动完成行并放置分号

在eclipse中,您可以点击"输入",IDE将自动将您带到行尾,并放置一个分号.

在IntelliJ中,如果你点击shift-enter,你会得到类似的行为,而不是添加分号.我已经阅读并尝试过cntrl-shift-enter,你会得到完全相同的行为.然而,这是一个非常难以使用的关键组合,至少比使用Eclipse的一键式方法要多得多.

有任何想法吗?

IntelliJ自动完成转义

eclipse intellij-idea

19
推荐指数
2
解决办法
6108
查看次数

C - 指针和不同的结果?

我无法弄清楚这一点.也许是因为凌晨2点.无论如何,我在这里不知所措.

#include <stdio.h>

int main()
{
    char array[] = "123456789";
    char* ptr = array;

    printf("%c\n", *(ptr++));
    printf("%c\n", *ptr);

    *ptr = array[3];
    printf("%c\n", *(ptr++));
    printf("%c\n\n", *ptr);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果是:

1
2
4
3
Run Code Online (Sandbox Code Playgroud)
  1. 我有一个指针,我指定array.

  2. 然后我打印,我认为将是第一个索引('2'),而是得到1.- 所以,我假设它*(ptr++)实际上是取消引用,然后才增加指针.

  3. 然后我重新分配ptr第四个索引('4')并重复步骤2.这样就可以正常工作,因为我看到C在解除引用之前不会先计算括号.

  4. 然后我打印新增加ptr的显示('5')...我得到了3

那是怎么回事,第1步和第2步以及第3步和第4步是相同的,但是我得到了不同的结果?

c pointers

14
推荐指数
2
解决办法
648
查看次数

在C中重用释放的指针

本网站上有很多关于在使用后释放指针的问题,并且进一步将它们设置为NULL.争论很激烈,主题看似平分.例如:这个问题.一般来说,我对释放指针很困惑.

想象一下,你有一个指向一些内存空间的指针.使用空格后,释放指针但不要将其设置为NULL.稍后,你有另一个指针调用malloc(),或者一些模拟,并且它被分配了内存,包括先前释放的内存(原始指针仍然指向).如果这个新指针写入此内存块,会发生什么?直觉上什么都不会发生,但前面提供的链接中的OP写道它会使程序崩溃.


所以我的问题是:

  1. 给定一个释放指针,是什么阻止您将指针重新分配给新的内存位置?为什么重用已释放的指针是"坏"的做法?如果调用free(ptr)只将此内存返回给操作系统,为什么不能将指针重新分配给其他内存位置并重新使用?

    char *ptr = malloc(sizeof(*ptr)); //first allocation
    free(ptr); //release memory 
    ptr = NULL; 
    ptr = malloc(sizeof(*ptr)); //reallocate
    
    Run Code Online (Sandbox Code Playgroud)
  2. 为什么要写入以前释放的内存块,仍然有原始指针,导致程序崩溃? - 请参阅上面链接的问题的第一篇文章的第一段(如果我误解了本段的意图,请解释,因为不明确是否再次使用该指针来写入内存或创建新指针.)

c free pointers

14
推荐指数
1
解决办法
9052
查看次数

C中的IF-ELSE语句快捷方式

对于速记IF-ELSE语句,C具有以下语法

    (integer == 5) ? (TRUE) : (FALSE);
Run Code Online (Sandbox Code Playgroud)

我经常发现自己只需要声明的一部分(TRUE或FALSE)并使用它

    (integer == 5) ? (TRUE) : (0);
Run Code Online (Sandbox Code Playgroud)

我只是想知道是否有办法不使用这种速记符号包含声明的ELSE部分?

c if-statement shortcut

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

在C中是否存在可以分配/转换为更具限制性的原型的通用函数指针?

我需要在运行时动态链接库并使用解析一系列函数dlsym.我的第一个想法是使用一个函数指针数组,通过利用char *表示符号名称的辅助数组,可以很容易地迭代.

但是,问题在于并非所有函数都使用相同的参数.有没有办法在数组中使用泛型函数指针,但是将它分配给限制性更强的函数指针原型?例如:

如果我需要解决这些功能:

int (*functionA)(int)
char (*functionB)(char,int)
Run Code Online (Sandbox Code Playgroud)

是否有可能做某些事情(伪似......)

void* functionList(...)[2] = {functionA, functionB};
Run Code Online (Sandbox Code Playgroud)

随着

char FuncNameA[] = "functionA";
char FuncNameB[] = "functionB";
char *functionNames[2] = {FuncNameA, FuncNameB};
Run Code Online (Sandbox Code Playgroud)

用于循环调用dlsym符号解析的目的

int i = 0;
for(; i<2; i++)
    functionList[i] = dlsym(DL_OPEN_HANDLE, functionNames[i]);
Run Code Online (Sandbox Code Playgroud)

其中DL_OPEN_HANDLE将由之前的调用定义dlopen.

c function-pointers dynamic-linking

12
推荐指数
3
解决办法
4544
查看次数

从内存中读取"零"比读取其他值更快吗?

我正在运行一个内存访问实验,其中使用了一个2D矩阵,每行都是一个内存页面的大小.该实验包括使用行/列主要读取每个元素,然后使用行/列主要写入每个元素.正在访问的矩阵是使用全局范围声明的,以简化编程要求.

这个问题的关键是,在静态声明测试矩阵的情况下,编译器将值初始化为零,我发现的结果非常有趣.当我第一次读取操作时,即

rowMajor_read();
colMajor_read();
rowMajor_write();
colMajor_write(); 
Run Code Online (Sandbox Code Playgroud)

然后我的colMajor_read操作很快就完成了. 在此输入图像描述

但是,如果我在阅读之前进行写操作,我们有:

rowMajor_write();
colMajor_write();
rowMajor_read();
colMajor_read(); 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

并且列主要读取操作增加了近一个数量级.

我认为它必须与编译器如何优化代码有关.由于每个元素的全局矩阵都相同,编译器是否完全删除了读取操作?或者以某种方式"更容易"从内存中读取相同为零的值?

我没有传递任何关于优化的特殊编译器命令,但我确实以这种方式声明了我的函数.

inline void colMajor_read(){
    register int row, col;
    register volatile char temp __attribute__((unused));
    for(col = 0; col < COL_COUNT; col++)
        for(row = 0; row < ROW_COUNT; row++)
            temp = testArray[row][col];
}
Run Code Online (Sandbox Code Playgroud)

因为我遇到了编译器temp从上面的函数中完全删除变量的问题,因为它从未被使用过.我认为,同时具有volatile__attribute__((unused))是多余的,但我把它不过.我的印象是没有对volatile变量实现优化.

有任何想法吗?


我查看了生成的程序集,结果与colMajor_read函数的结果相同.(汇编)非内联版本:http://pastebin.com/C8062fYB

c memory time

8
推荐指数
1
解决办法
143
查看次数

无论如何都要释放空指针或先检查?

假设我在一个程序中遇到一个实例,我要么释放一个NULL指针,要么首先检查它是否为NULL并跳过free()函数调用.

简单地释放NULL指针会更有效吗?我搜索了一下,显然,对于C89之后的实现,释放NULL指针是无害的 - 所以决定归结为效率.

我的假设是,在打电话时可能会产生相当多的开销free().因此,在调用free()函数之前,可能需要进行简单的逻辑检查.


tl;博士版,

在进行调用时,内部发生了什么free(),可能会在释放之前首先检查或指针是否为NULL,从而或多或少有效?

c memory free pointers

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

使用通配符导入类

如果我说:

import java.awt.event.ActionListener;
Run Code Online (Sandbox Code Playgroud)

我得到了ActionListener类.如果我说:

import java.awt.event.*;
Run Code Online (Sandbox Code Playgroud)

我得到包含 ActionListener 的事件类?或者更好的是:

import java.awt.*;
Run Code Online (Sandbox Code Playgroud)

我认为,如果你包括一个类,就像在前两个例子中那样,你有效地导入了该类并继承了它的所有子类.但是,当我仅使用最后一行时,例如,Eclipse经常显示错误,说它无法解析某些项目,并建议我同时包含java.awt和java.awt.event.

java import class

5
推荐指数
1
解决办法
1968
查看次数