ฉันเห็นคำตอบที่ถูกต้องที่นี่ แต่ฉันจะได้รับรายละเอียดเพิ่มเติมเล็กน้อย
ข้ามไปที่บทสรุปด้านล่างเพื่อดูคำตอบสำหรับคำถามหลักของคุณหากคุณไม่ต้องการอ่านเนื้อหาทั้งหมด
สิ่งที่เป็นนามธรรม
ดังนั้นในกรณีนี้ฉันต้องจ่ายเงินเพื่ออะไร
คุณจะจ่ายเงินสำหรับสิ่งที่เป็นนามธรรม ความสามารถในการเขียนรหัสที่ง่ายและเป็นมิตรกับมนุษย์มากขึ้นนั้นมีค่าใช้จ่าย ใน C ++ ซึ่งเป็นภาษาเชิงวัตถุเกือบทุกอย่างเป็นวัตถุ เมื่อคุณใช้วัตถุใด ๆ สิ่งสำคัญสามอย่างจะเกิดขึ้นภายใต้ประทุน:
- การสร้างวัตถุโดยทั่วไปการจัดสรรหน่วยความจำสำหรับวัตถุเองและข้อมูล
- การเริ่มต้นวัตถุ (มักจะผ่าน
init()
วิธีการบางอย่าง) โดยปกติการจัดสรรหน่วยความจำจะเกิดขึ้นภายใต้ประทุนเป็นสิ่งแรกในขั้นตอนนี้
- การทำลายวัตถุ (ไม่เสมอไป)
คุณไม่เห็นมันในโค้ด แต่ทุกครั้งที่คุณใช้อ็อบเจกต์ทั้งสามอย่างที่กล่าวมาจะต้องเกิดขึ้น หากคุณต้องทำทุกอย่างด้วยตนเองรหัสจะชัดเจนอีกต่อไป
ตอนนี้สิ่งที่เป็นนามธรรมสามารถทำอย่างมีประสิทธิภาพโดยไม่ต้องเพิ่มค่าใช้จ่าย: วิธีการอินไลน์และเทคนิคอื่น ๆ สามารถใช้งานได้โดยทั้งคอมไพเลอร์และโปรแกรมเมอร์เพื่อลบค่าโสหุ้ยของสิ่งที่เป็นนามธรรม แต่นี่ไม่ใช่กรณีของคุณ
เกิดอะไรขึ้นใน C ++
นี่มันพัง:
std::ios_base
ระดับเริ่มต้นซึ่งเป็นชั้นฐานสำหรับทุกอย่าง I / O ที่เกี่ยวข้อง
std::cout
วัตถุจะเริ่มต้นได้
- สตริงของคุณถูกโหลดและส่งผ่านไปยัง
std::__ostream_insert
ซึ่ง (ตามที่คุณคิดโดยใช้ชื่อแล้ว) เป็นวิธีการstd::cout
(โดยทั่วไปคือ<<
โอเปอเรเตอร์) ซึ่งเพิ่มสตริงลงในสตรีม
cout::endl
std::__ostream_insert
นอกจากนี้ยังมีการส่งผ่านไปยัง
__std_dso_handle
ถูกส่งไปยัง__cxa_atexit
ซึ่งเป็นฟังก์ชั่นระดับโลกที่รับผิดชอบในการ "ล้าง" ก่อนออกจากโปรแกรม __std_dso_handle
ตัวมันเองถูกเรียกใช้โดยฟังก์ชั่นนี้เพื่อจัดสรรคืนและทำลายวัตถุระดับโลกที่เหลืออยู่
ดังนั้นการใช้ C == ไม่จ่ายอะไรเลยเหรอ?
ในรหัส C มีขั้นตอนน้อยมากเกิดขึ้น:
- สตริงของคุณจะถูกโหลดและส่งผ่านไปยัง
puts
การedi
ลงทะเบียน
puts
ถูกเรียก
ไม่มีวัตถุใด ๆ จึงไม่จำเป็นต้องเริ่มต้น / ทำลายสิ่งใด
อย่างไรก็ตามเรื่องนี้ไม่ได้หมายความว่าคุณไม่ได้ "จ่ายเงิน" เพื่ออะไรใน C คุณยังคงจ่ายเงินเพื่อให้เป็นนามธรรมและการเริ่มต้นของไลบรารีมาตรฐาน C และการแก้ปัญหาแบบไดนามิกprintf
ฟังก์ชั่น (หรือที่จริงแล้วputs
ซึ่งปรับให้เหมาะสมโดยคอมไพเลอร์เนื่องจากคุณไม่ต้องการสตริงรูปแบบใด ๆ ) ยังคงเกิดขึ้นภายใต้ประทุน
หากคุณต้องเขียนโปรแกรมนี้ในแอสเซมบลีบริสุทธิ์มันจะมีลักษณะดังนี้:
jmp start
msg db "Hello world\n"
start:
mov rdi, 1
mov rsi, offset msg
mov rdx, 11
mov rax, 1 ; write
syscall
xor rdi, rdi
mov rax, 60 ; exit
syscall
ซึ่งโดยทั่วไปแล้วจะส่งผลให้เรียกใช้write
syscallตามด้วยexit
syscall ตอนนี้จะเป็นขั้นต่ำเปล่าเพื่อทำสิ่งเดียวกัน
เพื่อสรุป
C เป็นวิธีที่ไร้กระดูกมากขึ้นและทำขั้นต่ำเพียงอย่างเดียวที่จำเป็นเท่านั้นทำให้ผู้ใช้สามารถควบคุมได้อย่างเต็มที่ซึ่งสามารถเพิ่มประสิทธิภาพและปรับแต่งได้ตามต้องการ คุณบอกให้ตัวประมวลผลโหลดสตริงในรีจิสเตอร์จากนั้นเรียกใช้ฟังก์ชันไลบรารีเพื่อใช้สตริงนั้น C ++ ในอีกทางหนึ่งมีความซับซ้อนและเป็นนามธรรมมากขึ้น สิ่งนี้มีข้อได้เปรียบอย่างมากเมื่อเขียนรหัสที่ซับซ้อนและอนุญาตให้เขียนได้ง่ายขึ้นและเป็นมิตรกับมนุษย์มากขึ้น แต่เห็นได้ชัดว่ามีค่าใช้จ่าย มีเสมอจะเป็นอุปสรรคในการปฏิบัติงานใน C ++ ถ้าเทียบกับ C ในกรณีเช่นนี้ตั้งแต่c ++ มากกว่าสิ่งที่จำเป็นในการบรรลุงานขั้นพื้นฐานดังกล่าวและทำให้มันเพิ่มมากขึ้นค่าใช้จ่าย
ตอบคำถามหลักของคุณ :
ฉันต้องจ่ายเงินสำหรับสิ่งที่ไม่ได้กินหรือไม่?
ในกรณีนี้โดยเฉพาะใช่ คุณไม่ได้ใช้ประโยชน์จากสิ่งที่ C ++ มีให้มากกว่า C แต่เป็นเพราะไม่มีอะไรในรหัสง่ายๆที่ C ++ สามารถช่วยคุณได้: มันง่ายมากที่คุณไม่ต้องการ C ++ เลย
โอ้และอีกหนึ่งสิ่ง!
ข้อดีของ C ++ อาจดูไม่ชัดในตอนแรกเนื่องจากคุณเขียนโปรแกรมที่ง่ายและเล็ก แต่ดูตัวอย่างที่ซับซ้อนขึ้นเล็กน้อยและดูความแตกต่าง (ทั้งสองโปรแกรมทำสิ่งเดียวกัน)
ค :
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a, const void *b) {
return *(int*)a - *(int*)b;
}
int main(void) {
int i, n, *arr;
printf("How many integers do you want to input? ");
scanf("%d", &n);
arr = malloc(sizeof(int) * n);
for (i = 0; i < n; i++) {
printf("Index %d: ", i);
scanf("%d", &arr[i]);
}
qsort(arr, n, sizeof(int), cmp)
puts("Here are your numbers, ordered:");
for (i = 0; i < n; i++)
printf("%d\n", arr[i]);
free(arr);
return 0;
}
C ++ :
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void) {
int n;
cout << "How many integers do you want to input? ";
cin >> n;
vector<int> vec(n);
for (int i = 0; i < vec.size(); i++) {
cout << "Index " << i << ": ";
cin >> vec[i];
}
sort(vec.begin(), vec.end());
cout << "Here are your numbers:" << endl;
for (int item : vec)
cout << item << endl;
return 0;
}
หวังว่าคุณจะเห็นชัดเจนว่าฉันหมายถึงที่นี่ นอกจากนี้ให้สังเกตว่าใน C คุณต้องจัดการหน่วยความจำในระดับที่ต่ำกว่าโดยใช้อย่างไรmalloc
และfree
คุณจะต้องระมัดระวังเกี่ยวกับการจัดทำดัชนีและขนาดมากขึ้นอย่างไรและคุณต้องมีความเจาะจงมากเพียงใดเมื่อรับอินพุตและการพิมพ์