有没有办法让C更多地了解类型并确保类型安全?
考虑一下:
typedef unsigned cent_t;
typedef unsigned dollar_t;
#define DOLLAR_2_CENT(dollar) ((cent_t)(100*(dollar)))
void calc(cent_t amount) {
// expecting 'amount' to semantically represents cents...
}
int main(int argc, char* argv[]) {
dollar_t amount = 50;
calc(DOLLAR_2_CENT(amount)); // ok
calc(amount); // raise warning
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法让上面的代码至少提高gcc的警告?
我知道我可以使用C-structs来包装unsigneds并获得理想的结果,我只是想知道是否有更优雅的方法来实现它.
可以多一点吗?
如果我想检索和更新存储在TreeSet中的对象,该怎么办?
我问的原因是,我希望能够维护一些能够存储学生的数据结构.我希望它被排序(按成绩 - 这是学生的实例变量),并且 - 即使在我更新一个(或多个)成绩之后,它也需要保持排序.
因此,在简要查看了Java的集合之后,我决定使用TreeSet并设置一个比较器,按比例对两个学生进行比较.问题是,我刚发现TreeSet没有get()方法!
任何帮助和建议将不胜感激.
我试图围绕这个二进制数字的浮点表示,但我无法找到,无论我在哪里,都能找到一个很好的答案.
为什么指数有偏差?
旧的可靠的二次补码方法有什么问题?
我试着看一下维基百科关于这个主题的文章,但它所说的一切都是:"对于签名值的通常表示,会使比较变得更难."
我在计算机系统中读到程序员的观点,当用汇编代码编程时,关于调用者 - 被调用者协议的约定规定函数的返回值应该存储在eax(或模拟rax,在64位计算机中)寄存器.
我猜这是在C语言编程时"幕后"自动发生的事情,这意味着C编译器"知道"使用eax寄存器来返回函数返回值.
但是当返回的值是一个不适合32位eax或64位rax寄存器的大对象时,C++会发生什么?显然你不能使用堆栈传递它,那么编译器如何处理大对象的按值返回操作?
没关系一个大对象,C编译器如何处理大结构的返回值?
它是将它保存在临时内存空间中并将其地址作为返回值返回吗?如果是这样,它必须预测在运行期间要对函数执行多少次调用,有时这是不可能的,不是吗?
鉴于以下列表:
my_list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Run Code Online (Sandbox Code Playgroud)
我希望能够尽可能快速有效地将子列表my_list[2:4]与子列表交换my_list[7:10],以获得新列表:
new_list=[0, 1, 7, 8, 9, 4, 5, 6, 2, 3, 10, 11, 12]
Run Code Online (Sandbox Code Playgroud)
这是我的尝试:
def swap(s1, s2, l):
seg1=l[:s1.start]+l[s2]
seg2=l[s1.stop : s2.start]
seg3=l[s1]+l[s2.stop:]
return seg1+seg2+seg3
print swap(slice(2,4), slice(7,10), [0,1,2,3,4,5,6,7,8,9,10,11,12])
Run Code Online (Sandbox Code Playgroud)
这确实打印了所需的输出,虽然这样做对我来说很糟糕.
是否有一种更简单,更优雅的方式,不会为每个函数调用创建四个新列表?(我打算多打电话给这个功能)
我不介意(实际上我更喜欢)更改原始列表,而不是每个函数调用创建新实例.
这两种模式之间有什么区别,而不是意图,因为很明显它们解决了不同的问题,但在实施方面.
你能说,例如,解释器是一个退化的复合体吗?
你还能说些什么呢?
我知道这可能听起来像一个奇怪的问题,但我只是想知道C++中的类是否比具有相同数据字段的结构更重要,并且有一件事我无法找到答案...
考虑一下:
struct SomeStruct {
int a;
int b;
};
class SomeClass {
public:
SomeClass():a(0),b(0){}
private:
int a;
int b;
};
int main() {
std::cout<<sizeof(SomeStruct)<<std::endl; // output is 8
std::cout<<sizeof(SomeClass)<<std::endl; // output is 8
}
Run Code Online (Sandbox Code Playgroud)
但现在看看当我向SomeClass添加析构函数时会发生什么:
struct SomeStruct {
int a;
int b;
};
class SomeClass {
public:
SomeClass():a(0),b(0){}
virtual ~SomeClass(){}
private:
int a;
int b;
};
int main() {
std::cout<<sizeof(SomeStruct)<<std::endl; // output is 8 bytes
std::cout<<sizeof(SomeClass)<<std::endl; // output is 16 bytes!
}
Run Code Online (Sandbox Code Playgroud)
为什么SomeClass需要8个字节用于析构函数?
我一直在尝试围绕FIFO,并提出了一个简单的服务器和客户端程序.
我不是想做任何花哨的事情,只是为了让一个进程扮演'服务器'的角色,这个过程将"监听"另一个进程传递的任何消息; 客户端.
这是我写的:
server.c
#include<stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#define INGOING "clientToServer.fifo"
#define BUFFER 200
int main(int argc, char *argv[]) {
char in[BUFFER];
mkfifo(INGOING, 0666);
printf("Welcome to server.\n");
printf("channel for sending messages to server is %s\n", INGOING);
int in_fd=open(INGOING, O_RDONLY);
if (in_fd==-1) {
perror("open error");
exit(-1);
}
while (read(in_fd, in, BUFFER)>0) {
printf("You sent %s to server.\n", in);
}
return 2;
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,这是非常直接的,当我在后台运行它时,./server.out&它在read通话时被阻止并等待任何人写信clientToServer.fifo.到现在为止还挺好.
现在,考虑客户端:
client.c
#include<stdio.h>
#include<fcntl.h>
#include<string.h>
#define BUFFER 200
int main(int …Run Code Online (Sandbox Code Playgroud) 据我所知,堆栈假设向下增长.
我试着运行这段代码:
#include<stdio.h>
void func(char* a1, int a2, int a3) {
char b1[10];
int b2;
int b3;
printf("a3 address is: %p\n", &a3);
printf("a2 address is: %p\n", &a2);
printf("a1 address is: %p\n", &a1);
printf("-----------------------\n");
printf("b1 address is: %p\n", &b1);
printf("b2 address is: %p\n", &b2);
printf("b3 address is: %p\n", &b3);
}
int main() {
func("string",2,3);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果不像我预期的那样:
a3 address is: 0x7fff68473190
a2 address is: 0x7fff68473194
a1 address is: 0x7fff68473198
-----------------------
b1 address is: 0x7fff684731b0
b2 address is: 0x7fff684731a8
b3 address …Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
#include<gtk/gtk.h>
#include<stdio.h>
static void destroy(GtkWidget*, gpointer);
static gboolean mouse_moved(GtkWidget *widget,GdkEvent *event,gpointer user_data);
int main(int argc, char* argv[]) {
GtkWidget *main_window;
// initializing
gtk_init(&argc, &argv);
main_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(main_window),"Test");
gtk_widget_set_size_request (main_window, 500, 300);
// connect the window with signals
g_signal_connect (G_OBJECT (main_window), "destroy",G_CALLBACK (destroy), NULL);
g_signal_connect (G_OBJECT (main_window), "motion-notify-event",G_CALLBACK (mouse_moved), NULL);
gtk_widget_set_events(main_window, GDK_POINTER_MOTION_MASK);
// show window
gtk_widget_show_all (main_window);
gtk_main();
return 0;
}
static void destroy(GtkWidget *window,gpointer data) {
gtk_main_quit ();
}
static gboolean mouse_moved(GtkWidget *widget,GdkEvent *event, gpointer user_data) {
if (event->type==GDK_MOTION_NOTIFY) { …Run Code Online (Sandbox Code Playgroud)