从C/C++到Go

wx592a7561e9493 · · 470 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

参考链接: C++ wcsspn()

很多程序员都是从c/c++转到go的,难免会产生一些混淆, 在学习go语言的时候,尤其要注意与c/c++的区别, 对比起来学习效果可能更好。下面这个总结很不错, 直接引用过来学习:http://hyperpolyglot.org/c 

  

Hyperpolyglot 

C, Go 

a side-by-side reference sheet 

grammar and invocation | variables and expressions | arithmetic and logic | strings | regexes | dates and time | fixed-length-arrays | resizable arrays | dictionaries | functions | execution control | concurrency | file handles | files | directories| processes and environment | option parsing | libraries and namespaces | user-defined types | c preprocessor macros | net and web | unit tests | debugging and profiling 

version cgoversion used  C11, gcc 4.8, clang 3.51.4show version  $ gcc --version$ go versionimplicit prologue#include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <wchar.h>import "fmt"grammar and invocation cgohello world$ cat hello.c #include <stdio.h> int main(int argc, char **argv) {   printf("Hello, World!\n"); } $ gcc hello.c $ ./a.out Hello, World!$ cat hello.go package main import "fmt" func main() {   fmt.Printf("Hello, World!\n") } $ go build hello.go $ ./hello Hello, World!file suffixessource, header, object file.c .h .o statement separator;; or sometimes newlinea new line terminates a statement when the last token on the line is   (1) an identifier,   (2) a numeric, character, or string literal,   (3) one of the keywords break, continue,       fallthrough, or return,   (4) one of ++, --, ), ], or }block delimiters  { … }{ … }end-of-line comment  // comment// commentmultiple line comment/* comment lineanother line *//* comment lineanother line */variables and expressions cgovariable/* if inside function, memory allocated on stack: */ int i; int j = 3; /* memory allocated on heap: */ int *ptr = malloc(sizeof *ptr); /* if malloc fails, it returns NULL and sets errno to ENOMEM */ *ptr = 7;// memory allocated on stack: var i int // allocated on stack; type inferred from literal: j := 3 // memory allocated on heap: ptr := new(int) *ptr = 7free heap  free(ptr);none; uses garbage collectionglobal variable/* in foo.c, outside of any function: */ int x = 7; /* to declare in bar.c: */ extern int x;// foo.go: package foo // capitalized top-level identifiers are exported: var X = 7 // bar.go: package bar import foo // package scope: var y = 3 func baz() {   // local scope:   var z = 5   fmt.Println(foo.X + y + z) }uninitialized variableThe behavior of reading from uninitialized stack variables or unitialized memory allocated by malloc is undefined. Global and static variables are zero-initialized. Heap variables allocated by calloc have their bytes zeroed.Every type has a zero value. For numeric types it is zero and for strings it is the empty string.compile time constant/* usually preprocessor is used: */ #define PI 3.14const Pi = 3.14immutable variableconst int i = rand();noneassignmenti = 3;// defines variable of appropriate type: i := 3 // variable must already be declared: i = 3parallel assignmentnone// define variables of appropriate type: m, n := 3, 7 // x and y must already be declared: x, y = 2, 8swapint x = 1, y = 2, tmp; tmp = x; x = y; y = tmp;x, y = y, xcompound assignmentarithmetic: += -= *= /= %=bit: <<= >>= &= |= ^=arithmetic: += -= *= /= %=bit: <<= >>= &= |= ^=increment and decrementpremodifiers: ++i --ipostmodifiers: i++ i--postmodifiers only; cannot be used in expressions: i++ i--addressint i = 3; int* ptr = &i;i := 3 var ptr *int ptr = &i ptr2 := &idereference  int i2 = *ptr;i2 := *ptrtype size/* put type inside parens: */ sizeof (int) /* expressions and values don't require parens: */ sizeof 1 + 1import "unsafe" // use expression or name of variable with type: unsafe.Sizeof(i) unsafe.Sizeof(1 + 1)address arithmeticint a[] = {3, 2, 1, 0}; for (int *p = a; *p; ++p) {   printf("%d\n", *p); }nonenull  /* pointer types only: */ NULL// cannot be stored in numeric or string variable: nilnull test  ptr == NULLptr == nilconditional expression  x > 0 ? x : -xnonearithmetic and logic cgoboolean type  int /* includes type for consistency with C++: */ #include <stdbool.h> boolbooltrue and false  1 0 /* includes identifiers for consistency with C++: */ #include <stdbool.h> true falsetrue falsefalsehoods  0 0.0 NULL falsefalselogical operators  && || !&& || !relational operators  == != < > <= >=== != < > <= >=integer typesigned char 1+ bytes short int 2+ bytes int 2+ bytes long int 4+ bytes long long int 4+ bytestypes with portable sizes are defined in stdint.h: int8_t int16_t int32_t int64_tint int8 int16 int32 int64unsigned typeunsigned char: 1+ bytes unsigned short int 2 bytes+ unsigned int 2 bytes+ unsigned long int 4+ bytes unsigned long long int 4+ bytestypes with portable sizes are defined in stdint.h: uint8_t uint16_t uint32_t uint64_tuint8 (byte) uint16 uint32 uint64float typefloat 4 bytes double 8 bytes long double 16 bytesregisters may be larger on some systemsfloat32 float64arithmetic operators  + - * / %+ - * / %integer division  3 / 73 / 7integer division by zero  system dependent; process often sent a SIGFPE signalon Unix, process sent a SIGFPE signalfloat division  3 / (float)73 / float32(7)float division by zero/* these are float values but not literals: */ inf, nan, or -inf// these are float values but not literals: +Inf, NaN, or -Inf // to get the float values: import "math" math.Inf(1) math.Nan() math.Inf(-1)power#include <math.h> pow(2.0, 3.0)import "math" math.Pow(2.0, 3.0)sqrt#include <math.h> sqrt(2);include "math" math.Sqrt(2)sqrt -1#include <math.h> /* nan */ double x = sqrt(-1.0);import "math" // NaN x := math.Sqrt(-2.0) import "math/cmplx" // (0+1.41421356i) z := cmplx.Sqrt(-2.0)transcendental functions#include <math.h> exp log log2 log10 sin cos tan asin acos atan atan2include "math" math.Exp math.Log math.Log2 math.Log10 math.Sin math.Cos math.Tan math.Asin math.Acos math.Atan math.Atan2transcendental constants#include <math.h> M_PI M_Eimport "math" math.Pi Math.Efloat truncation#include <math.h>   double d = 3.77;   long trunc = (long)d; long rnd = round(d); long flr = floorl(d); long cl = ceill(d);include "math" x = 3.77 trunc := int(x)none flr := int(math.Floor(x)) cl := int(math.Ceil(x))absolute value#include <math.h>  /* fabs() */ int i = abs(-7); float x = fabs(-7.77);include "math"none math.Abs(-7.77)complex typefloat complex 8 bytes double complex 16 bytes long double complex 32 bytescomplex64 complex128complex construction#include <complex.h> double complex z; z = 1.0 + 2.0 * I; /* C11: */ double complex z = CMPLX(1.0, 2.0);var z complex128 = 1.0 + 2.0icomplex decompositionreal and imaginary component, argument, absolute value, conjugate#include <complex.h> double x; double complex w; x = creal(z); x = cimag(z); x = carg(z); x = cabs(z); w = conj(z);import "math/cmplx" var x float64 var w complex128 x = real(z) x = imag(z) x = cmplx.Phase(z) x = cmplx.Abs(z) w = cmplx.Conj(z)random numberuniform integer, uniform float/* lrand48 returns value in [0, 2**31 - 1]: */ long n = lrand48(() % 100; /* Value in interval [0.0, 1.0): */ double x = drand48();import "math/rand" n := rand.Intn(100) x := rand.Float64()random seedsrand48(17);import "math/rand" rand.Seed(17)bit operators  << >> & | ^ ~<< >> & | none ^strings cgostring type  char * wchar_t * wchar_t is typically 32 bits on Linux and 16 bits on Windows.stringstring literal  /* string in initialized data segment: */ char *s = "hello"; wchar_t *ws = L"hello"; /* string in heap: */ char *s2 = strdup(s); wchar_t *ws2 = wcsdup(ws); /* if strdup cannot allocate memory, it returns NULL and sets    errno to ENOMEM. */"hello" // raw string literal: `hello`newline in string literal/* compiler concatenates literals    separated by whitespace: */ char *s = "first line\n"   "second line";// backquote literals only: let s := `first line second line`string escapes\a \b \f \n \r \t \v \" \' \? \\ \o \oo \ooo \xhh \uhhhh \UhhhhhhhhDouble quote literals only: \a \b \f \n \r \t \v \\ \" \ooo \xhh \uhhhh \Uhhhhhhhhexpression interpolationnone compare strings/* == and < compare memory addresses: */ strcmp("hello", "world") == 0 strcmp("hello", "world") < 0 wcscmp(L"hello", L"world") == 0 wcscmp(L"hello", L"world") < 0"hello" == "world" "hello" < "world"string to number/* conversion functions:     strtol strtoll     strtoul strtoull     strtof strtod strtold */ #include <limits.h> char *s = "101 dalmations"; char *rest; long n = strtol(s, &rest, 10); if (n == 0 && errno == EINVAL)   printf("invalid input\n"); else if ((n == LONG_MAX || n == LONG_MIN) && errno == ERANGE)   printf("overflow\n"); else   printf("%ld %s\n", n, rest); /* wide string conversion functions:     wcstol wcstoll     wcstoul wcstoull     wcstof wcstod wcstold */import "strconv" //2nd arg is base, 3rd arg is size of int in bits: i, _ := strconv.ParseInt("17", 10, 32) // 2nd arg is size of float in bits: x, _ := strconv.ParseFloat("3.14", 32)number to stringlong n = 1234; char buf[100]; snprintf(buf, 100, "%ld", n); wchar_t buf2[100]; swprintf(buf2, 100, L"%ld", n); /* some format specifiers:     %d %ld %lld     %u %lu %llu     %.3f %.3e */import "strconv" //3rd arg is precision after decimal point; // 4th arg is size of float in bits: strconv.FormatFloat(3.14, 'f', 4, 32) // 2nd arg is base: strconv.FormatInt(7, 10)split/* strtok_r modifies 1st arg */ char *s = strdup("foo,bar baz"); char *sep = " ,"; char *tok, *last; /* tok is never an empty string: */ for (tok = strtok_r(s, sep, &last);      tok;      tok = strtok_r(NULL, sep, &last))   printf("token: %s\n", tok); /* also wcstok */import "strings" s := "foo bar baz" parts := strings.Split(s, " ")join  noneimport "strings" parts := []string{"foo", "bar", "baz"} s := strings.Join(parts, " ")concatenatechar *s1 = "hello"; char *s2 = " world"; size_t len = strlen(s1) + strlen(s2) + 1; char *s3 = (char *)calloc(len, sizeof *s3); strcpy(s3, s1); strcat(s3, s2); /* also wcscpy and wcscat */"hello" + " world"replicatenoneimport "strings" hbar := strings.Repeat("-", 80)extract substringchar target[3]; char *source = "hello"; strncpy(target, source + 2, 2); target[2] = '\0'; /* also wcsncpy */"hello"[2:4]index of substringconst char *s = "hello"; const char *p = strstr("hello", "ll"); size_t idx = p ? p - s : -1; /* also wcsstr */import "strings" // zero-based index; -1 if not found: strings.Index("hello", "ll")format stringchar buf[100]; snprintf(buf, 100, "%s: %d", "Spain", 7); wchar_t buf2[100]; swprintf(buf2, 100, L"%S: %d", L"Spain", 7); translate caseto upper, to lowerchar *s = strdup("hello"); int i; for (i=0; i < strlen(s); ++i)   s[i] = toupper(s[i]); for (i=0; i < strlen(s); i++)   s[i] = tolower(s[i]); /* also towupper and towlower */import "strings" strings.ToUpper("hello") strings.ToLower("HELLO")trimboth sides, on left, on rightchar *s = strdup(" lorem "); size_t i, j; /* trim left */ for (i = 0; s[i] && isspace(s[i]); ++i); if (i)   for (size_t j = 0; j < strlen(s) - i + 1; ++j)     s[j] = s[j + i]; /* trim right */ for (i = strlen(s) - 1; s[i] && isspace(s[i]); —i); s[i + 1] = '\0'; /* also iswspace */import "strings" s := " lorem " strings.Trim(s, " ") strings.TrimLeft(s, " ") strings.TrimRight(s, " ")padchar buf[100]; /* pad right: */ snprintf(buf, 100, "%-10s", "hello"); /* pad left: */ snprintf(buf, 100, "%10s", "hello"); /* also swprintf */ length  strlen("hello") wcslen(L"hello")len("hello")character typechar wchar_trunecharacter literal'A' L'A' character lookup"lorem ipsum"[6] L"lorem ipsum"[6] character indexchar *s = "aaa bbb ccc"; char *p; size_t n; p = strchr(s, ' '); if (p)   printf("first space at %ld\n", p - s); p = strrchr(s, ' '); if (p)   printf("last space at %ld\n", p - s); n = strspn(s, "abc"); printf("first %ld chars in set\n", n); p = strpbrk(s, " ,:."); printf("first %ld chars not in set\n", n); /* also: wcschr wcsrchr wcsspn wcspbrk */ character tests#include <ctype.h> #include <wctype.h> isascii isrune iscntrl isgraph isalpha isspace isupper islower isalnum isdigit isxdigit ispunct /* also: iswascii, iswrune, ... */ chr and ord/* Character types are integer types so no conversion is necessary. Use %c and %C to print a character like a string of length one. */ char ch = 'A'; wchar_t ch2 = L'A'; int i = ch + 7; int i2 = ch2 + 7; wprintf(L"%c %d %C %d\n", ch, ch, ch2, ch2); regular expressions cgometacharacters/* REG_BASIC: */ . [ ] \ * ^ $ /* REG_EXTENDED: */ . [ ] \ ( ) * + ? { } | ^ $. [ ] \ ( ) * + ? { } | ^ $use raw string (i.e. backtick) literals to avoid having to escape backslashes.character class abbrevations/* matches any character; does not match newline if    REG_NEWLINE is used: */ . /* more character classes available in pcre library */. \d \D \s \S \w \Wanchors/* match beginning and end of string; match beginning and    end of line if REG_NEWLINE is used: */ ^ $^ $ \A \b \B \zmatch test#include <regex.h> regex_t rx; int retval; char *pat = "1999"; char *s = "It's 1999"; /* Use REG_NOSUB if 4th arg to regexec() is NULL */ if (retval = regcomp(&rx, pat, REG_EXTENDED | REG_NOSUB)) {   char buf[200];   regerror(retval, &rx, buf, 200);   fprintf(stderr, "regex error: %s\n", buf); } else {   if (regexec(&rx, s, 0, NULL, 0) == 0)     printf("Party!\n");   regfree(&rx); }import "regexp" var rx = regexp.MustCompile("1999") if (rx.MatchString("It's 1999.")) {   fmt.Println("Party!") }case insensitive match test#include <regex.h> regex_t rx; int retval; char *pat = "lorem"; char *s = "Lorem"; if (retval = regcomp(&rx, pat, REG_EXTENDED | REG_ICASE)) {   char buf[200];   regerror(retval, &rx, buf, 200);   fprintf(stderr, "Regex error: %s\n", buf); } else {   if (regexec(&rx, s, 0, NULL, 0) == 0)     printf("case insensitive match\n");   regfree(&rx); }import "regexp" var rx = regexp.MustCompile("(?i)lorem") if (rx.MatchString("Lorem Ipsum")) {   fmt.Println("case insensitive match") }modifiers/* bit flags used in 3rd arg of regcomp(): */ REG_BASIC REG_EXTENDED REG_ICASE REG_NOSUB REG_NEWLINE// use (?i), (?m), ... to insert in regex: i m s Usubstitution import "regexp" s := "do re mi mi mi" var rx = regexp.MustCompile("mi") fmt.Println(rx.ReplaceAllString(s, "ma"))group capture#include <regex.h> regex_t rx; int retval; char *pat = "([0-9]{4})-([0-9]{2})-([0-9]{2})"; char *s = "2010-06-03"; if (retval = regcomp(&rx, pat, REG_EXTENDED)) {   char buf[200];   regerror(retval, &rx, buf, 200);   fprintf(stderr, "Regex error: %s\n", buf); } else {   /* first match is entire pattern */   regmatch_t matches[4];   if (regexec(&rx, s, 4, matches, 0) == 0) {     char yr[5];     regmatch_t rm = matches[1];     /* rm_so and rm_eo contain index of start and end of        match; they are set to -1 if unused */     strncpy(yr, s + rm.rm_so, rm.rm_eo - rm.rm_so);     yr[5] = '\0';     printf("year is %s\n", yr);   }   regfree(&rx); } dates and time cgounix epoch type  time_tint64broken-down datetime typestruct tmTimecurrent unix epochtime_t now; if (time(&now) == -1)   perror("time failed");import "time" t := time.Now().Unix()current datetime import "time" dt := time.Now()broken-down datetime to unix epoch/* use host local time as tz: */ time_t t = mktime(&dt); /* use UTC as tz: */ time_t t2 = timegm(&dt2);t := dt.Unix()unix epoch to broken-down datetimestruct tm dt, dt2; if (!localtime_r(&now, &dt))   perror("localtime_r failed"); /* UTC: */ if (!gmtime_r(&now, &dt2))   perror("gmtime_r failed");var t int64 = 1421929926 var ns int64 = 0 dt := time.Unix(t, ns)format datetimechar buf[100]; char *fmt = "%Y-%m-%d %H:%M:%S"; if (!strftime(buf, 100, fmt, &dt))   fputs("strftime failed\n", stderr);layout := "2006-01-02 15:04:05" fmt.Println(dt.Format(layout))parse datetimechar *s = "1999-09-10 23:30:00"; char *fmt = "%Y-%m-%d %H:%M:%S"; char *p = strptime(s, fmt, &dt3); if (!p)   fputs("strptime failed\n", stderr);layout := "2006-01-02:15:04:05" dt, err := time.Parse(layout, "1999-09-10 23:30:00")date subtraction/* use mktime for local; timegm for utc: */ double delta_sec = difftime(mktime(&dt), mktime(&dt2));var delta time.Duration delta = dt.Sub(dt2)add durationdt.tm_sec += 1000; mktime(&dt); dt.tm_hour += 1000; mktime(&dt); dt.tm_mday += 1000; mktime(&dt);dt2 := dt + 1000 * time.Second dt3 := dt + 1000 * time.Hourdate partsint yr = dt.tm_year + 1900; int mo = dt.tm_mon + 1; int dy = dt.tm_mday;yr := dt.Year() var mo time.Month = dt2.Month() dy := dt.Day()time partsint hr = dt.tm_hour; int mi = dt.tm_min; int ss = dt.tm_sec;hr := dt.Hour() mi := dt.Minute() ss := dt.Second()build broken-down datetimedt.tm_year = 1999 - 1900; dt.tm_mon = 9 - 1; dt.tm_mday = 10; dt.tm_hour = 23; dt.tm_min = 30; dt.tm_sec = 0; dt.tm_isdst = 1; dt.tm_gmtoff = -7 * 60 * 60; if (mktime(&dt) == -1)   fputs("mktime failed\n", stderr);import "time" yr := 1999 var mo time.Month = 9 dy, hr, mi, ss, ns := 10, 23, 30, 0, 0 loc, _ := time.LoadLocation("Local") dt := time.Date(yr, mo, dy, hr, mi, ss, ns, loc)local time zone determinationOn a Unix system, the local time zone is stored in /etc/localtime. A process can have a different local time zone by setting the TZ environment variable. time zone infoname and utc offset in hoursoffset abbreviation: dt.tm_zoneUTC offset in hours: dt.tm_gmtoff / 3600.0name, offset_sec := dt.Zone()offset abbreviation: nameUTC offset in hours: offset_sec / 3600.0daylight savings test  dt.tm_isdst microseconds#include <sys/time.h> struct timeval t; if (gettimeofday(&t, NULL) == -1)   perror("gettimeofday failed"); else   printf("epoch: %lu usec: %u\n", t.tv_sec, t.tv_usec);dt.Nanosecond() / 1000fixed-length arrays cgodeclareint a[10];// values are zero-initialized: var a [10]intallocate on stack/* contents of memory undefined: */ int a[10];compiler decides location in memoryallocate on heap#include <stdlib.h> /* memory zero-initialized: */ int *a = calloc(10, sizeof *a);compiler decides location in memoryfree heap  free(a);none; garbage collectedliteral  int a[] = {1, 2, 3};a := []int{1, 2, 3}size   len(a)lookup  a[0]a[0]update  a[0] = 4;a[0] = 4out-of-bounds behaviorundefined, possible SIGSEGVpanic: index out of rangeif compiler detects a problem the code won't compileelement indexchar *a[3] = {"foo", "bar", "baz"}; int loc = -1, i; for (i = 0; i < 3; ++i) {   if (strcmp("bar", a[i]) == 0) {     loc = i;     break;   } }a := []string{"foo", "bar", "baz"} loc := -1 for i, val := range a {   if val == "bar" {     loc = i   } }sliceint *a2; a2 = a[2];a := []string{"a", "b", "c", "d", "e"} // {"c", "d"}: a2 := a[2:4]slice to end a := []string{"a", "b", "c", "d", "e"} // {"c", "d", "e"}: a2 := a[2:]concatenate a := []int{1, 2, 3} a2 := []int{4, 5, 6} a3 := append(a, a2...)copy a := []int{1, 2, 3} a2 := a // also sets a[0] to 4: a2[0] = 4 a3 := make([]int, len(a)) copy(a3, a) // a[0] is unchanged: a3[0] = 5iterate over elementsint a[10]; for (i = 0; i < 10; ++i ) {   a[i] = i * i; } iterate over indices and elements  reverse import "sort" a := []int{1, 2, 3} sort.Sort(sort.Reverse(sort.IntSlice(a)))sortint compare(const void *a, const void *b) {   if (*(int *)a < *(int *)b) {     return -1;   }     else if (*(int *)a == *(int *)b) {     return 0;   }   else {     return 1;   } } int a[5] = {6, 8, 10, 9, 7}; /* 2nd arg is array length; 3rd arg is element size */ qsort(a, 5, sizeof (int), &compare); resizable arrays cgodeclare // slice of length 5; capacity 10: a := make([]int, 5, 10)literal a := []int{1, 2, 3}size   len(a) // number of elements that can be stored in allocated memory; // runtime reallocates when needed: cap(a)lookup   a[0]update   a[0] = 4out-of-bounds behavior panic: index out of rangeif compiler detects a problem the code won't compileelement index a := []string{"foo", "bar", "baz"} loc := -1 for i, val := range a {   if val == "bar" {     loc = i   } }slice a := []string{"a", "b", "c", "d", "e"} // {"c", "d"}: a2 := a[2:4]slice to end a := []string{"a", "b", "c", "d", "e"} // {"c", "d", "e"}: a2 := a[2:]manipulate back a := []int{1, 2, 3} a = append(a, 4) num := a[len(a) - 1] a = a[:len(a) - 1]manipulate front  concatenate a := []int{1, 2, 3} a2 := []int{4, 5, 6} a3 := append(a, a2...)copy a := []int{1, 2, 3} a2 := a // also sets a[0] to 4: a2[0] = 4 a3 := make([]int, len(a)) copy(a3, a) // a[0] is unchanged: a3[0] = 5iterate over elements a := []string{"do", "re", "mi"} for _, s := range(a) {   fmt.Printf("value: %s\n", s) }iterate over indices and elements a := []string{"do", "re", "mi"} for i, s := range(a) {   fmt.Printf("value at %d: %s\n", i, s) }reverse import "sort" a := []int{1, 2, 3} sort.Sort(sort.Reverse(sort.IntSlice(a)))sort  map nonefilter nonereduce nonedictionaries cgodeclare   d := make(map[string]int)literal   d := map[string]int {"t": 1, "f": 0}size   len(d)lookup   d["t"]update   d["t"] = 2missing key behavior   returns zero value for value typeis key present // If key not present, val will contain // zero value for type and ok will contain false: val, ok = d["y"]]delete   delete(d, "f")iterate for k, v := range d {   fmt.Printf("%s: %d\n", k, v) }keys and values as arrays  functions cgodefine functionint add(int n, int m) {   return n + m; }func add(n int, m int) int {   return n + m } // parameters can share type declaration: func add(n, m int) int {   return n + m }invoke function  add(3, 7)add(3, 7)forward declaration of functionfloat add(float x, float y); /* if a function invocation is encountered before a   declaration or a definition, the arguments and the   return value are assumed to have type 'int' */ printf("%f\n", add(2.2, 3.5)); float add(float x, float y) {   return x + y; }// function can be invoked before definition fmt.Printf("%f\n", add(2.2, 3.5)) func add(n float32, m float32) float32 {   return n + m }overload functionnot permittednot permittednest functionnot permittednot permitteddefault value for parameternonenonevariable number of arguments#include <stdarg.h> char* concat(int cnt, ...) {   int i, len;   va_list ap;   char *retval, *arg;   va_start(ap, cnt);   for (i = 0, len = 0; i < cnt; i++) {     len += strlen(va_arg(ap, char*));   }   va_end(ap);   retval = calloc(len + 1, sizeof *retval);   va_start(ap, cnt);   for (i = 0, len = 0; i < cnt; i++) {     arg = va_arg(ap, char*);     strcpy(retval + len, arg);     len += strlen(arg);   }   va_end(ap);   return retval; } char *s = concat(4, "Hello", ", ", "World", "!");func concat(strs ...string) string {   var ret = ""   for _, str := range strs {     ret += str   }   return ret }named parametersnonenonepass by valuevoid use_integer(int i) {   function body } int i = 7; use_integer(i); pass by addressvoid use_iptr(int *i) {   function body } int i = 7; use_iptr(&i); pass by referencenot possible return valuereturn argreturn arg. If return values have names and no arguments are provided to return the values assigned to the return variables are used.no return value/* declare function void: */ void print_err(char *msg) {   fprintf(stderr, msg); } multiple return valuesnot permittedfunc divmod(m, n int) (int, int) {   return m / n, m % n } q, r := divmod(7, 3)named return valuesnonefunc divmod(m, n int) (q, r int) {   q = m / n   r = m % n   return } q, r := divmod(7, 3)execute on return import "os" // prints "x is 7" func x_is_7() {   x := 7   defer fmt.Println(x)   x = 8   defer os.Stdout.WriteString("x is ") }anonymous function literalnone invoke anonymous function  function with private stateint counter() {   static int n = 0;   return ++n; } function as valueint add(int m, int n) {   return m + n; } /* a function cannot be stored in a variable, but   its address can */ int (* fp)(int, int) = &add; printf("1 + 2: %d\n", (*fp)(1, 2)); execution control cgoifint signum; if (i > 0) {   signum = 1; } else if (i == 0) {   signum = 0; } else {   signum = -1; }var signum int if x > 0 {   signum = 1 } else if x == 0 {   signum = 0 } else {   signum = -1 }switch/* switch expression must be an integer */ switch (i) { case 0: case 1:   printf("i is boolean\n");   break; default:   printf("i is not a boolean\n");   break; } /* use "break" to prevent falling through */// switch expression can have any type switch i { case 0, 1:   fmt.Println("i is boolean") default:   fmt.Println("i is not a boolean") } // use "fallthrough" to fall throughwhileint i = 0; while (i < 10) {   ++i; }i := 0 for i < 10 {   i++ }forint i, n; for (i = 1, n = 1; i <= 10; ++i) {   n *= i; }var i, n int // Initialization and afterthought must be single // statements; there is no comma operator. n = 1 for i = 1; i <= 10; i++ {   n *= i; }for with local scopenonen := 1 for i := 1; i <= 10; i++ {   n *= i; } // i is no longer in scopeinfinite loopfor (;;) {   /* code */ } while (1) {   /* code */ }for {   // code }break  breakbreakbreak from nested loopsuse goto or flag variable  var a, b int Outer:   for a = 1; ; a++ {     for b = 1; b < a; b++ {       c := int(math.Sqrt(float64(a * a + b * b)))       if c * c == a * a + b * b {         break Outer       }     }   }continue  continuecontinuesingle statement branches and loopswhile (n % 17 != 0)   ++n; if (n < 0)   printf("negative\n");// braces are mandatory: if n < 0 {   fmt.Println("negative") }dangling elseint a = 1, b = -3, c; /* indentation shows how ambiguity is resolved */ if (a > 0)   if (b > 0)     c = 1;   else     c = 2; /* gcc warns about dangling else; -Werror turns warnings into errors */no ambiguitygoto  if (err) {     goto cleanup;   }   /* code */ cleanup:   printf("cleaning up...\n");  if err {     goto Cleanup   }   // code Cleanup:   fmt.Println("cleaning up...")longjump#include <setjmp.h> void callee(jmp_buf env) {   longjmp(env, 1);   /* unreachable */ } void caller() {   jmp_buf env;   switch (setjmp(env)) {   case 0:     callee(env);     /* unreachable */     break;   case 1:     printf("returned from callee\n");     break;   default:     printf("unexpected setjump value\n");   } }nonefinally block  concurrency cgosleep#include <unistd.h> /* seconds */ int retval = sleep(10); if (retval != 0) {   printf("interupted with %d s to go", retval); } /* microseconds */ if (usleep(10000)) {   perror("usleep failed"); }dur := time.Duration(10 * time.Second) time.Sleep(dur) dur2 := time.Duration(10000 * time.Microsecond) time.Sleep(dur2)timeout  start thread#include <pthread.h> typedef struct {   int id; } payload; void* thread(void* arg) {   payload* pl = (payload*)arg;   printf("the value is %d\n", pl->id); } pthread_t thr; payload pl = {3}; if (pthread_create(&thr, NULL, &thread, (void*)&pl)) {   printf("failed to create thead\n");   exit(1); } terminate current thread#include <pthread.h> payload pl = {7}; pthread_exit((void*)&pl); terminate other thread#include <pthread> pthread_t thr; payload pl = {3}; if (pthread_create(&thr, NULL, &thread, (void*)&pl)) {   printf("failed to create thead\n");   exit(1); } sleep(5); if (pthread_cancel(thr)) {   printf("failed to cancel thread\n");   exit (1); } list threadsno portable way wait on thread  lock  create message queue  send message  receive message  file handles cgostandard file handlesstdin stdout stderrimport "os" os.Stdin os.Stdout os.Stderrread line from stdinchar *line = NULL; size_t cap = 0; ssize_t len; /* if line is not NULL, it should be memory allocated by    malloc and the size should be in cap. If size is not    sufficient getline will call realloc on line */ len = getline(&line, &cap, stdin); if (len == -1) {   if (ferror(stdin)) {     perror("getline err");   }   else if (feof(stdin)) {     fprintf(stderr, "end of file\n");   } } else {   /* use line here */   free(line); }import "bufio" import "os" var line string var err error b := bufio.NewReader(os.Stdin) line, err = b.ReadString('\n') if err != nil {   os.Stderr.WriteString("error!") } else {   // use line here }write line to stdout/* returns EOF on error */ int retval = puts("Hello, World!");import "os" os.Stdout.WriteString("Hello, World!\n")write formatted string to stdout  printf("count: %d\n", 7); wprintf(L"count: %d\n", 7);fmt.Printf("count: %d\n", 7)open file for reading/* returns NULL on error */ FILE *f = fopen("/etc/hosts", "r");raw, err := os.Open("/etc/hosts") if err == nil {   f := bufio.NewReader(f) }open file for writing/* returns NULL on error */ FILE *f = fopen("/tmp/test", "w"); open file for appending/* returns NULL on error */ FILE *f = fopen("/tmp/err.log", "a"); close file/* returns EOF on error */ int retval = fclose(f); close file implicitlynonedeferi/o errorsFunctions return values such as EOF, NULL, or -1 to indicate error. Some functions return the value of errno. In some cases errors are not distinguished from end-of-file. The functionsferror() and feof() can be used to test a file handle. The type of error is stored in errno. strerror(errno) or the thread safe strerror_r(errno, buf, buflen) convert the errors code to a string and perror() writes its argument to stderr withsterror(errno). read linechar line[BUFSIZ]; if (fgets(line, BUFSIZ, f) == NULL) {   if (ferror(stdin)) {     perror("getline err");   }   else if (feof(stdin)) {     fprintf(stderr, "end of file\n");   } } else {   if ('\n' == line[strlen(line) - 1]) {     /* use line here */ } else {     fprintf(stderr, "long line truncated\n"); } iterate over file by line  read file into array of strings  read file into string  write string/* returns EOF on error */ int retval = fputs("Hello, World!", f); write line/* returns EOF on error */ int retval = fputs("Hello, World!\n", f); flush file handleif (fflush(f) == EOF) {   perror("fflush failed"); } end-of-file test  feof(f) get and set file handle positionlong pos; if ((pos = ftell(f)) == -1) {   perror("ftell failed"); } /* 3rd arg can also be SEEK_CUR or SEEK_END */ if (fseek(f, 0, SEEK_SET) == -1) {   perror("fseek failed"); } open unused file#include <limits.h>  /* PATH_MAX */ #include <unistd.h> char buf[PATH_MAX]; strcpy(buf, "/tmp/foo.XXXXXX"); /* terminal Xs will be replaced: */ int fd = mkstemp(buf); if (fd != -1) {   FILE *f = fdopen(fd, "w");   if (NULL == f) {     perror("fdopen failed");   } else {     /* use f */   } } else {   perror("mkstemp failed"); } files cgofile test, regular file test  #include <sys/stat.h> #include <unistd.h>  /* access() */ struct stat buf; if (access("/tmp/foo", F_OK) >= 0) {   /* file exists */ } if (stat("/tmp/foo", &buf) != 0) {   perror("stat failed"); } else if (S_ISREG(buf.st_mode)) {   /* file is regular */ }import "os" fi, err := os.Stat("/tmp/foo") if os.IsNotExist(err) {   fmt.Printf("Does not exit\n") } else {   fmt.Printf("Exists\n")   fm := fi.Mode()   if fm.IsRegular() {     fmt.Printf("Is Regular")   } else {     fmt.Printf("Is Not Regular")   } }file size  #include <sys/stat.h> struct stat buf; if (stat("/tmp/foo", &buf) != 0) {   perror("stat failed"); } else {   printf("size: %llu\n", buf.st_size); }fi.Size()is file readable, writable, executable#include <unistd.h> if (access("/etc/hosts", R_OK) != 0) {   printf("not readable\n"); } if (access("/etc/hosts", W_OK) != 0) {   printf("not writable\n"); } if (access("/etc/hosts", X_OK) != 0) {   printf("not executable\n"); } set file permissions#include <sys/stat.h> if (chmod("/tmp/foo", 0755) == -1) {   perror("chmod failed"); }import "os" err := os.Chmod("/tmp/foo", 0755) if err != nil {   fmt.Printf("Chmod failed\n") }last modification time  copy file, remove file, rename file/* no copy function in standard library */ if (remove("/tmp/foo")) {   perror("remove failed"); } if (rename("/tmp/bar", "/tmp/foo")) {   perror("rename failed"); }import "os" // no copy function in standard library err := os.Remove("/tmp/foo") if err != nil {   fmt.Printf("Remove failed: %s\n", err) } err2 := os.Rename("/tmp/bar", "/tmp/foo") if err2 != nil {   fmt.Printf("Rename failed: %s\n", err2) }create symlink, symlink test, readlink#include <limits.h>  /* PATH_MAX */ #include <sys/stat.h> #include <unistd.h> if (symlink("/etc/hosts", "/tmp/hosts") == -1) {   perror("symlink failed"); } struct stat sbuf; if (stat("/tmp/hosts", &buf) != 0) {   perror("stat failed"); } else if (S_ISLNK(buf.st_mode)) {   /* file is symlink */ } char pbuf[PATH_MAX + 1]; ssize_t size = readlink("/tmp/hosts", pbuf, PATH_MAX); if (size >= 0 ) {   pbuf[size] = 0;   /* pbuf now contains null-terminated string      with target path */ }import "os" err := os.Symlink("/etc/hosts", "/tmp/hosts") if err != nil {   fmt.Printf("Symlink failed: %s\n", err) } fi, err2 := os.Lstat("/tmp/hosts") if err2 == nil {   fm := fi.Mode()   if fm & os.ModeSymlink != 0 {     fmt.Println("File is a Symlink")   } } else {   fmt.Printf("Lstat failed: %s\n", err2) } s, err3 := os.Readlink("/tmp/hosts") if err3 != nil {   fmt.Printf("Readlink failed: %s\n", err3) } else {   fmt.Printf("Link target: %s\n", s) }generate unused file name/* if first argument is NULL, path is in system temp    directory. Caller should free() return value. */ char *path = tempnam("/tmp", "foo");import "io/ioutil" // Uses system tmp dir if 1st arg is empty string: f, err := ioutil.TempFile("/tmp", "foo") if err == nil {   fmt.Printf("writing to: %s\n", f.Name())   f.WriteString("foo content") }directories cgoworking directory import "os" dir, err := os.Getwd() if err != nil {   os.Stderr.WriteString("Gtwd failed\n") } else {   fmt.Printf("pwd: %s\n", dir) } err2 := os.Chdir("/tmp") if err2 != nil {   os.Stderr.WriteString("Chdir failed\n"); }build pathname import "path" pathname := path.Join("/etc", "hosts") fmt.Printf("path: %s\n", pathname)dirname and basename#include <libgen.h> char *s1 = strdup("/etc/hosts"); char *s2 = strdup("/etc/hosts"); /* Check whether s1 or s2 are NULL. */ /* Some implementations return pointers to statically allocated    memory which is overwritten by subsequent calls;    others modify the input string. */ char *s3 = dirname(s1); char *s4 = basename(s2);import "path" path.Dir("/etc/hosts") path.Base("/etc/hosts")absolute pathnamechar *s; if ((s = realpath("..", NULL)) == NULL) {   perror("realpath failed"); } else {   /* use s */ } iterate over directory by file#include <dirent.h> DIR *dir = opendir("/etc"); struct dirent *de; while (de = readdir(dir)) {   printf("%s\n", de->d_name); } closedir(dir);import "io/ioutil" a, err := ioutil.ReadDir("/etc") if err == nil {   for _, fi := range a {     fmt.Printf("name: %s\n", fi.Name())   } }glob paths#include <glob.h> glob_t pglob; int i; glob("/etc/*", 0, NULL, &pglob); for (i = 0; i < pglob.gl_pathc; ++i) {   printf("%s\n", pglob.gl_pathv[i]); } globfree(&pglob);import "path/filepath" a, err := filepath.Glob("/etc/*") if err == nil {   for _, path := range(a) {     fmt.Printf("path: %s\n", path)   } }make directory#include <sys/stat.h> if (mkdir("/tmp/foo")) {   fprintf(stderr, "mkdir err: %s\n", strerror(errno)); }err := os.Mkdir("/tmp/foo", 0775) if err != nil {   fmt.Printf("Mkdir failed: %s\n", err) }recursive copy  remove empty directory#include <unistd.h> if (rmdir("/tmp/foo") == -1) {   perror("rmdir failed"); }err := os.Remove("/tmp/foo") if err != nil {   fmt.Printf("Remove failed: %s", err) }remove directory and contents err := os.RemoveAll("/tmp/foo") if err != nil {   fmt.Printf("RemoveAll failed: %s", err) }directory test  #include <sys/stat.h> struct stat buf; if (stat("/tmp/foo", &buf) != 0) {   perror("stat failed"); } else if (S_ISDIR(buf.st_mode)) {   /* file is directory */ } generate unused directory#include <limits.h> char buf[PATH_MAX]; strcpy(buf, "/tmp/fooXXXXXX"); /* terminal Xs will be replaced: */ if (mkdtemp(buf) == NULL) {   perror("mkdtemp failed"); } else {   /* use buf */ }import "io/ioutil" // Uses system tmp dir if 1st arg is empty string: path, err := ioutil.TempDir("/tmp", "foo") if err == nil {   fmt.Printf("dir path: %s\n", path) }system temporary file directory/* defined in <stdio.h> */ P_tmpdirimport "os" path := os.TempDir()processes and environment cgocommand line argumentsint main(int argc, char **argv) {   if (argc > 1)     printf("first arg: %s\n", argv[1]);   return 0; }import "os" if len(os.Args) > 1 {   fmt.Printf("first arg: %\n", os.Args[1]) }program nameint main(int argc, char **argv) {   printf("program name: %s\n", argv[0]);   return 0; }import "os" fmt.Printf("program name: %s\n", os.Args[0])environment variable#include <stdlib.h> char *home = getenv("HOME"); setenv("EDITOR", "emacs", 1); unsetenv("EDITOR");import "os" home := os.Getenv("HOME") err := os.Setenv("EDITOR", "emacs") if err != nil {   fmt.Printf("Setenv failed: %s\n", err) }iterate over environment variablesextern char **environ; char **env, *p, *key; for (env = environ; *env; ++env) {   p = strchr(*env, '=');   if (p) {     size_t keylen = p - *env;     key = strndup(*env, keylen);     printf("key: %s value: %s\n", key, *env + keylen + 1);     free(key);   } }import "os" import "strings" for _, s := range os.Environ() {   a := strings.SplitN(s, "=", 2)   fmt.Printf("key: %s value: %s\n", a[0], a[1]) }get user id and name#include <unistd.h>  /* getlogin */ printf("uid: %d\n", getuid()); printf("username: %s\n", getlogin());import "os" os.Getuid() /* username? */exit/* use 0 for success; 1 through 127 for failure */ exit(1);import "os" os.Exit(1)executable test#include <unistd.h> if (access("/bin/ls", X_OK) != 0) {   printf("not executable\n"); } external command/* retval of -1 indicates fork or wait failed.    127 indicates shell failed */ int retval = system("ls -l *"); fork  exec  pipe  wait  get pid, parent pid#include <unistd.h> /* getpid() and getppid() have return type pid_t */ printf("%d\n", getpid()); printf("%d\n", getppid())import "os" fmt.Println(os.Getpid()) fmt.Println(os.Getppid())set signal handler#include <signal.h> /* assumes a POSIX environment */ void handle_signal(int signo) {   int restore = errno;   switch(signo) {   case SIGUSR1:     write(1, "caught SIGUSR1\n", 15);     break;   default:     break;   }   errno = restore; } /* 2nd arg can also be SIG_IGN or SIG_DFL */ sig_t prev_handler = signal(SIGUSR1, &handle_signal); if (prev_handler == SIG_ERR) {   perror("signal failed");   exit(1); } send signal#include <signal.h> #include <unistd.h>  /* getppid */ if (kill(getppid(), SIGUSR1) == -1) {   perror("kill failed"); } option parsing cgogetopt#include <getopt.h> /* 2nd value indicates whether option takes an argument */ static struct option long_opts[] = {   {"debug", no_argument, NULL, 'd'},   {"threshold", required_argument, NULL, 't'},   {0, 0, 0, 0} }; int debug = 0; double threshold = 0.0; char *file = NULL; int ch; int opti; char *endptr; while (1) {   ch = getopt_long(argc, argv, "dt:", long_opts, &opti);   if (-1 == ch) {     break;   }   switch (ch) {   case 'd':     debug = 1;     break;   case 't':     threshold = strtod(optarg, &endptr);     if (*endptr != 0) {       fprintf(stderr, "expected float: %s\n", optarg);       exit(1);     }     break;   default:     fprintf(stderr, "unexpected arg: %d\n", ch);     exit(1);   } } /* optind is index of 1st arg not consumed by getopt */ if (optind != argc - 1) {   fputs("USAGE: foo [--multi] [--threshold=NUM] FILE\n",         stderr);   exit(1); } else {   file = argv[optind]; } libraries and namespaces cgoload library/* The library must also be linked:      $ gcc foo.o main.c    If the library is in an archive:      $ gcc -lfoo main.c */ #include "foo.h"import "foo" // Only capitalized identifiers are visible: var bar = foo.GetBar()load library in subdirectory#include "lib/foo.h"import "lib/foo"library pathAdd directory to path searched by #include directive: $ gcc -I/home/fred/include foo.cAdd directory to path searched by -l (lowercase L) option: $ gcc -L/home/fred/lib -lbar foo.cThe installation libraries are in the GOROOT directory. Additional directories can be listed in the GOPATH environment variable. The directories are separated by colons (semicolons) on Unix (Windows). Each directory contains a src subdirectory containing source code and a pkg/ARCH subdirectory containing compiled libraries.declare namespacenone// A package declaration must be first statement // in every source file.. package fooalias namespace  noneimport fu "foo"unqualified import of namespacenoneimport . "foo"unqualified import of definitions  package managersearch, install, list installed  user-defined types cgotypedeftypedef int customer_id; customer_id cid = 3; enumenum day_of_week {   mon, tue, wed, thu, fri, sat, sun }; enum day_of_week dow = tue; struct definitionstruct medal_count {   const char* country;   int gold;   int silver;   int bronze; };type MedalCount struct {   country string   gold int   silver int   bronze int }struct declaration  struct medal_count spain; struct initializationstruct medal_count spain = {"Spain", 3, 7, 4}; struct medal_count france = {   .gold = 8,   .silver = 7,   .bronze = 9,   .country = "France" };spain := MedalCount{"Spain", 3, 2, 1} france := MedalCount{   bronze: 9,   silver: 7,   gold: 8,   country: "France"}struct literalstruct medal_count france; france = (struct medal_count) {   .gold = 8,   .silver = 7,   .bronze = 9,   .country = "France" }; struct member assignmentspain.country = "Spain"; spain.gold = 3; spain.silver = 7; spain.bronze = 4;france := MedalCount{} france.country = "France" france.gold = 7 france.silver = 6 france.bronze = 5struct member accessint spain_total = spain.gold + spain.silver + spain.bronze;france_total = france.gold +   france.silver +   france.bronzec preprocessor macros cgoinclude file/* search path include system directories: */ #include <stdio.h> /* search path also includes directory of source file */ #include "foo.h" add system directory$ gcc -I/opt/local/include foo.c define macro#define PI 3.14 command line macro$ gcc -DPI=3.14 foo.c undefine macro#undef PI macro with arguments#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) stringify macro argument  concatenate tokens  conditional compilation#if defined __WIN32   win32_prinft("%f\n", x); #else   printf("%f\n", x); #endif macro operatorsThe conditional of #if can contain integer literals and the following operators: && || ! == != < > <= >= + - * / % << >> & | ^ ~In addition, the defined() operator can be used to test whether a macro is defined. #ifdef FOO is a shortcut for #if defined(FOO) net and web cgohttp get import "io/ioutil" import "net/http" resp, err := http.Get("http://www.google.com") if err == nil {   defer resp.Body.Close()   body, err := ioutil.ReadAll(resp.Body)   if err == nil {     fmt.Println(string(body))   } }unit tests cgounit test example$ sudo apt-get install check $ cat > check_foo.c #include <check.h> START_TEST(test_foo) {   fail_unless(0, "not true"); } END_TEST Suite * suite_foo(void) {   Suite *ste = suite_create("suite: foo");   TCase *tc = tcase_create("case: foo");   tcase_add_test(tc, test_foo);   suite_add_tcase(ste, tc);   return ste; } int main(void) {   int number_failed;   Suite *ste = suite_foo();   SRunner *sr = srunner_create(ste);   srunner_run_all(sr, CK_NORMAL);   number_failed = srunner_ntests_failed(sr);   srunner_free(sr);   return (number_failed); } $ gcc -o check_foo check_foo.c -lcheck $ ./check_foo Running suite(s): foo 0%: Checks: 1, Failures: 1, Errors: 0 check_foo.c:4:F:foo:test_foo:0: not equal equality assertionfail_unless(1 == 2, "integers not equal"); char *s = "lorem"; fail_unless(strcmp(s, "ipsum"), "strings not equal"); setup and teardown  unit test coverage  debugging and profiling cgocheck syntax$ gcc -fsyntax-only foo.c flag for stronger warnings$ gcc -Wall foo.c suppress warnings$ gcc -w foo.c treat warnings as errors$ gcc -Werror foo.c lint$ sudo apt-get install splint $ splint foo.c source cleanup  run debugger$ gcc -g -o foo foo.c $ gdb foo debugger commandshelp, list source, (re)load executable, next, step, set breakpoint, show breakpoints, delete breakpoint, continue, backtrace, up stack, down stack, print, run, quit> h > l [FIRST_LINENO, LAST_LINENO] > file PATH > n > s > b [FILE:]LINENO > i > d NUM > c > bt > up > do > p EXPR > r [ARG1[, [ARG2 ...]] > q cpu usage#include <sys/times.h> #include <unistd.h>  /* sysconf */ struct tms start, end; double ticks_per_s = (double)sysconf(_SC_CLK_TCK); clock_t start_wall = times(&start); if (start_wall < 0) {   fputs("times failed", stderr);   return (1); } int i; for (i = 0; i < 1000 * 1000 * 1000; ++i) {   /* empty loop */ } clock_t end_wall = times(&end); if (end_wall < 0) {   fputs("times failed", stderr);   return (1); } clock_t wall = end_wall - start_wall; clock_t user = end.tms_utime - start.tms_utime; clock_t system = end.tms_stime - start.tms_stime; printf("wall: %f s\n", wall / ticks_per_s); printf("user: %f s\n", user / ticks_per_s); printf("system: %f s\n", system / ticks_per_s); profile codedoes not work on Mac OS X $ gcc -pg -o foo foo.c $ ./foo $ gprof foo memory tool$ sudo apt-get install valgrind $ gcc -o foo foo.c $ valgrind foo  __________________________________________________________________________________________________________________________________



有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:wx592a7561e9493

查看原文:从C/C++到Go

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

470 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传