- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在将新开关信号引入现有测试图形用户界面时遇到 sigsegv 故障。
UI 有 3 个可能的事件源,两个事件框和一个开关。单击事件框时,它们的行为正常,但是如果切换了开关,则单击其中一个事件框会导致 segv(行为 1)。
此外,如果从新运行,首先切换开关然后单击事件框也会导致 segv(行为 2)。两者的 segv 始终出现在同一位置(如果使用其中一个事件框作为示例),如下所示:
if (((interface *) toggle)->eth0->ip_enabled) {
就代码而言,我能想到的最简单的表现形式如下(请原谅包含):
/*
* STRIPPED DOWN VERSION
*/
#include <arpa/inet.h>
#include <gtk/gtk.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define IPV4_ENABLED 1
#define IPV4_DISABLED 0
#define SELECTED 1
typedef struct {
int ip_enabled;
} net;
typedef struct {
net *eth0;
net *wlan0;
int type;
} interface;
typedef enum {
IT_ETH0,
IT_WLAN0,
IT_UNASSIGNED = 999,
} interface_type;
typedef struct {
int active;
interface *port;
int debug;
} test_parameters;
void wired (net *eth0);
void wifi (net *wlan0);
int main (int argc, char *argv[]) {
GtkBuilder *builder;
GtkWidget *window;
GError *gtk_error = NULL;
net *eth0 = g_slice_new (net);
net *wlan0 = g_slice_new (net);
interface *toggle = g_slice_new (interface);
test_parameters *test = g_slice_new (test_parameters);
test->port->type == IT_UNASSIGNED;
/*Add interfaces to struct "interface" */
toggle->eth0 = eth0;
toggle->wlan0 = wlan0;
toggle->eth0->ip_enabled = 0;
toggle->wlan0->ip_enabled = 0;
if (NULL == toggle->eth0)
fprintf (stdout, "%s\n", "eth0 is null ");
if (NULL == toggle->wlan0)
fprintf (stdout, "%s\n", "wlan0 is null ");
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder, "glade/window_main.glade", NULL)) {
fprintf (stdout, "%s%s\n", "Error loading file with the reason: ", gtk_error->message);
g_free (gtk_error);
exit (EXIT_FAILURE);
}
window = GTK_WIDGET (gtk_builder_get_object (builder, "window_main"));
gtk_builder_connect_signals (builder, toggle);
gtk_builder_connect_signals (builder, test);
g_object_unref (builder);
wired (eth0);
wifi (wlan0);
gtk_widget_show (window);
gtk_main ();
g_slice_free (net, eth0);
g_slice_free (net, wlan0);
g_slice_free (interface, toggle);
return 0;
}
void wifi (net *wlan0) {
if (1) {
wlan0->ip_enabled = IPV4_ENABLED;
}
}
void wired (net *eth0) {
if (1) {
eth0->ip_enabled = IPV4_ENABLED;
}
}
G_MODULE_EXPORT gboolean on_eventbox_image_wired_button_press_event (GtkWidget *widget,
GdkEvent *event, gpointer toggle) {
if (((interface *) toggle)->eth0 == NULL) {
printf("%s\n", "WIRED: eth0 IS NULL - REMOVE ME");
}
if (((interface *) toggle) == NULL) {
printf("%s\n", "WIRED: toggle IS NULL - REMOVE ME");
}
if (((interface *) toggle)->eth0->ip_enabled) {
printf("%s\n", "WIRED: eth0 is ip enabled - REMOVE ME");
((interface *) toggle)->type = IT_ETH0;
if (((interface *) toggle)->wlan0->ip_enabled) {
printf("%s\n", "WIRED: wlan0 is ip enabled, adjust - REMOVE ME");
}
}
return 0;
}
G_MODULE_EXPORT gboolean on_eventbox_image_wifi_button_press_event (GtkWidget *widget,
GdkEvent *event, gpointer toggle) {
/* Check to see if we have IP address so we can change the colour otherwise leave it red */
if (((interface *) toggle)->wlan0->ip_enabled) {
printf("%s\n", "WLAN has IP enabled");
((interface *) toggle)->type = IT_ETH0;
if (((interface *) toggle)->eth0->ip_enabled) {
printf("%s\n", "WLAN: eth0 is ip enabled, adjust - REMOVE ME");
}
}
return 0;
}
G_MODULE_EXPORT gboolean on_switch_test_on_state_set (GtkSwitch *widget,
gboolean state, gpointer test) {
(((test_parameters *) test)->active) = state;
fprintf (stdout, "%s%i\n", "Signal fired and the state is ", state);
return 0;
}
void on_window_main_destroy () {
gtk_main_quit ();
}
gdb bt 是:
(gdb) run
Starting program: /home/j2/simplified_example/simplified_example
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffed0c4700 (LWP 6979)]
[New Thread 0x7fffec8c3700 (LWP 6980)]
WIRED: eth0 is ip enabled - REMOVE ME
WIRED: wlan0 is ip enabled, adjust - REMOVE ME
Signal fired and the state is 1
Thread 1 "simplified_exam" received signal SIGSEGV, Segmentation fault.
0x0000000000401110 in on_eventbox_image_wired_button_press_event (widget=0x6a7260 [GtkEventBox], event=0x994cb0, toggle=0x624800)
at src/simplified_example1.c:134
134 if (((interface *) toggle)->eth0->ip_enabled) {
(gdb) bt
#0 0x0000000000401110 in on_eventbox_image_wired_button_press_event (widget=0x6a7260 [GtkEventBox], event=0x994cb0, toggle=0x624800)
at src/simplified_example1.c:134
#5 0x00007ffff728008f in <emit signal ??? on instance 0x6a7260 [GtkEventBox]> (instance=instance@entry=0x6a7260, signal_id=<optimised out>, detail=detail@entry=0) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./gobject/gsignal.c:3441
#1 0x00007ffff76bafac in _gtk_marshal_BOOLEAN__BOXED (closure=0x6ffe50, return_value=0x7fffffffd940, n_param_values=<optimised out>, param_values=0x7fffffffd9a0, invocation_hint=<optimised out>, marshal_data=<optimised out>) at /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gtk/gtkmarshalers.c:86
#2 0x00007ffff7264fa5 in g_closure_invoke (closure=0x6ffe50, return_value=return_value@entry=0x7fffffffd940, n_param_values=2, param_values=param_values@entry=0x7fffffffd9a0, invocation_hint=invocation_hint@entry=0x7fffffffd920) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./gobject/gclosure.c:804
#3 0x00007ffff7276fc1 in signal_emit_unlocked_R (node=node@entry=0x653b40, detail=detail@entry=0, instance=instance@entry=0x6a7260, emission_return=emission_return@entry=0x7fffffffdab0, instance_and_params=instance_and_params@entry=0x7fffffffd9a0)
at /build/glib2.0-prJhLS/glib2.0-2.48.2/./gobject/gsignal.c:3629
#4 0x00007ffff727f7f9 in g_signal_emit_valist (instance=<optimised out>, signal_id=<optimised out>, detail=<optimised out>, var_args=var_args@entry=0x7fffffffdb60) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./gobject/gsignal.c:3395
#6 0x00007ffff77f8c3c in gtk_widget_event_internal (widget=0x6a7260 [GtkEventBox], event=0x994cb0)
at /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gtk/gtkwidget.c:7692
#7 0x00007ffff76b83be in propagate_event (topmost=<optimised out>, event=<optimised out>, widget=0x6a7260 [GtkEventBox])
at /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gtk/gtkmain.c:2527
#8 0x00007ffff76b83be in propagate_event (widget=<optimised out>, event=0x994cb0, captured=<optimised out>, topmost=0x0)
at /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gtk/gtkmain.c:2629
#9 0x00007ffff76ba1bc in gtk_main_do_event (event=0x994cb0) at /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gtk/gtkmain.c:1850
#10 0x00007ffff66dcd92 in gdk_event_source_dispatch (source=<optimised out>, callback=<optimised out>, user_data=<optimised out>)
at /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gdk/x11/gdkeventsource.c:369
#11 0x00007ffff6f8e197 in g_main_context_dispatch (context=0x640980) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./glib/gmain.c:3154
---Type <return> to continue, or q <return> to quit---
#12 0x00007ffff6f8e197 in g_main_context_dispatch (context=context@entry=0x640980) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./glib/gmain.c:3769
#13 0x00007ffff6f8e3f0 in g_main_context_iterate (context=0x640980, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimised out>)
at /build/glib2.0-prJhLS/glib2.0-2.48.2/./glib/gmain.c:3840
#14 0x00007ffff6f8e712 in g_main_loop_run (loop=0x8d14b0) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./glib/gmain.c:4034
#15 0x00007ffff76b9395 in gtk_main () at /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gtk/gtkmain.c:1241
#16 0x0000000000401065 in main (argc=1, argv=0x7fffffffdfd8) at src/simplified_example1.c:97
(gdb)
(gdb)
(gdb)
请提前感谢您对此提供的任何帮助。
编辑:根据要求添加了 glade 文件 - 出于测试目的对其进行了简化:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="window_main">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Main Window</property>
<property name="default_width">640</property>
<property name="default_height">480</property>
<property name="decorated">False</property>
<signal name="destroy" handler="on_window_main_destroy" swapped="no"/>
<child>
<object class="GtkFixed" id="fixed_background">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImage" id="image_background">
<property name="name">4</property>
<property name="width_request">640</property>
<property name="height_request">480</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-missing-image</property>
</object>
</child>
<child>
<object class="GtkEventBox" id="eventbox_image_wired">
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible_window">False</property>
<property name="above_child">True</property>
<signal name="button-press-event" handler="on_eventbox_image_wired_button_press_event" swapped="no"/>
<child>
<object class="GtkImage" id="image_wired">
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="icon_name">applications-graphics</property>
</object>
</child>
</object>
<packing>
<property name="x">35</property>
<property name="y">20</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox_image_wifi">
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible_window">False</property>
<property name="above_child">True</property>
<signal name="button-press-event" handler="on_eventbox_image_wifi_button_press_event" swapped="no"/>
<child>
<object class="GtkImage" id="image_wifi">
<property name="width_request">101</property>
<property name="height_request">71</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="icon_name">accessories-text-editor</property>
</object>
</child>
</object>
<packing>
<property name="x">200</property>
<property name="y">20</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid_test_parameter">
<property name="width_request">582</property>
<property name="height_request">116</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">10</property>
<property name="column_spacing">4</property>
<child>
<object class="GtkSwitch" id="switch_test_on">
<property name="use_action_appearance">True</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="state-set" handler="on_switch_test_on_state_set" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="x">15</property>
<property name="y">245</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
最佳答案
问题出在这两行:
gtk_builder_connect_signals (builder, toggle);
gtk_builder_connect_signals (builder, test);
当您使用此函数时,传递给连接信号的 user_data 将应用于所有信号处理程序。
如果您选择此路径,那么您的用户数据应包含所有相关数据,并且处理程序必须相应地处理它。
问题是您的信号处理程序期望不同的东西,但您给它们相同的数据。
来自gtk_builder_connect_signals
:
user_data
user data to pass back with all signals
那你能做什么呢?
如果您想保持相同的方法,那么,例如,让我们创建一个包含所有相关数据的结构,然后将其传递给回调/信号处理程序:
typedef struct {
interface *toggle;
test_parameters *test;
} app_user_data;
然后初始化内容:
app_user_data *user_data = g_slice_new (app_user_data);
user_data->toggle = toggle;
user_data->test = test;
删除多余的 gtk_builder_connect_signals
并用我们的新结构替换一个:
gtk_builder_connect_signals (builder, user_data);
现在,所有的回调都可以使用他们需要的数据:
G_MODULE_EXPORT gboolean on_eventbox_image_wired_button_press_event (GtkWidget *widget, GdkEvent *event, gpointer toggle) {
app_user_data *user_data = (app_user_data *) toggle;
if (((interface *) user_data->toggle)->eth0 == NULL) {
printf("%s\n", "WIRED: eth0 IS NULL - REMOVE ME");
}
...
G_MODULE_EXPORT gboolean on_eventbox_image_wifi_button_press_event (GtkWidget *widget, GdkEvent *event, gpointer toggle) {
app_user_data *user_data = (app_user_data *) toggle;
/* Check to see if we have IP address so we can change the colour otherwise leave it red */
if (((interface *) user_data->toggle)->wlan0->ip_enabled) {
...
G_MODULE_EXPORT gboolean on_switch_test_on_state_set (GtkSwitch *widget, gboolean state, gpointer test) {
app_user_data *user_data = (app_user_data *) test;
(((test_parameters *) user_data->test)->active) = state;
...
带有建议更改的代码应该是这样的:
/*
* * STRIPPED DOWN VERSION
* */
#include <arpa/inet.h>
#include <gtk/gtk.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define IPV4_ENABLED 1
#define IPV4_DISABLED 0
#define SELECTED 1
typedef struct {
int ip_enabled;
} net;
typedef struct {
net *eth0;
net *wlan0;
int type;
} interface;
typedef enum {
IT_ETH0,
IT_WLAN0,
IT_UNASSIGNED = 999,
} interface_type;
typedef struct {
int active;
interface *port;
int debug;
} test_parameters;
typedef struct {
interface *toggle;
test_parameters *test;
} app_user_data;
void wired (net *eth0);
void wifi (net *wlan0);
int main (int argc, char *argv[]) {
GtkBuilder *builder;
GtkWidget *window;
GError *gtk_error = NULL;
net *eth0 = g_slice_new (net);
net *wlan0 = g_slice_new (net);
interface *toggle = g_slice_new (interface);
test_parameters *test = g_slice_new (test_parameters);
test->port->type == IT_UNASSIGNED;
/*Add interfaces to struct "interface" */
toggle->eth0 = eth0;
toggle->wlan0 = wlan0;
toggle->eth0->ip_enabled = 0;
toggle->wlan0->ip_enabled = 0;
app_user_data *user_data = g_slice_new (app_user_data);
user_data->toggle = toggle;
user_data->test = test;
if (NULL == toggle->eth0)
fprintf (stdout, "%s\n", "eth0 is null ");
if (NULL == toggle->wlan0)
fprintf (stdout, "%s\n", "wlan0 is null ");
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder, "glade/window_main.glade", NULL)) {
fprintf (stdout, "%s%s\n", "Error loading file with the reason: ", gtk_error->message);
g_free (gtk_error);
exit (EXIT_FAILURE);
}
window = GTK_WIDGET (gtk_builder_get_object (builder, "window_main"));
gtk_builder_connect_signals (builder, user_data);
g_object_unref (builder);
wired (eth0);
wifi (wlan0);
gtk_widget_show (window);
gtk_main ();
g_slice_free (net, eth0);
g_slice_free (net, wlan0);
g_slice_free (interface, toggle);
return 0;
}
void wifi (net *wlan0) {
if (1) {
wlan0->ip_enabled = IPV4_ENABLED;
}
}
void wired (net *eth0) {
if (1) {
eth0->ip_enabled = IPV4_ENABLED;
}
}
G_MODULE_EXPORT gboolean on_eventbox_image_wired_button_press_event (GtkWidget *widget, GdkEvent *event, gpointer toggle) {
app_user_data *user_data = (app_user_data *) toggle;
if (((interface *) user_data->toggle)->eth0 == NULL) {
printf("%s\n", "WIRED: eth0 IS NULL - REMOVE ME");
}
if (((interface *) user_data->toggle) == NULL) {
printf("%s\n", "WIRED: toggle IS NULL - REMOVE ME");
}
if (((interface *) user_data->toggle)->eth0->ip_enabled) {
printf("%s\n", "WIRED: eth0 is ip enabled - REMOVE ME");
((interface *) toggle)->type = IT_ETH0;
if (((interface *) user_data->toggle)->wlan0->ip_enabled) {
printf("%s\n", "WIRED: wlan0 is ip enabled, adjust - REMOVE ME");
}
}
return 0;
}
G_MODULE_EXPORT gboolean on_eventbox_image_wifi_button_press_event (GtkWidget *widget, GdkEvent *event, gpointer toggle) {
app_user_data *user_data = (app_user_data *) toggle;
/* Check to see if we have IP address so we can change the colour otherwise leave it red */
if (((interface *) user_data->toggle)->wlan0->ip_enabled) {
printf("%s\n", "WLAN has IP enabled");
((interface *) user_data->toggle)->type = IT_ETH0;
if (((interface *) user_data->toggle)->eth0->ip_enabled) {
printf("%s\n", "WLAN: eth0 is ip enabled, adjust - REMOVE ME");
}
}
return 0;
}
G_MODULE_EXPORT gboolean on_switch_test_on_state_set (GtkSwitch *widget, gboolean state, gpointer test) {
app_user_data *user_data = (app_user_data *) test;
(((test_parameters *) user_data->test)->active) = state;
fprintf (stdout, "%s%i\n", "Signal fired and the state is ", state);
return 0;
}
void on_window_main_destroy () {
gtk_main_quit ();
}
它应该可以编译,而不是像以前那样出现段错误!
关于c - GTK C 段 : Adding new signal causes segv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47908499/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!