test1.c
#include <stdio.h> void out(); int main(char*args[]){ out(); getchar(); return 0; }
test2.c
#include <stdio.h> void out() { printf("test test"); }
$ gcc -c test1.c
$ gcc -c test2.c
$ gcc test1.o test2.o -o test
$ ./test
test test
ソフトウェアエンジニアの技術ブログ:Software engineer tech blog
随机应变 ABCD: Always Be Coding and … : хороший
test1.c
#include <stdio.h> void out(); int main(char*args[]){ out(); getchar(); return 0; }
test2.c
#include <stdio.h> void out() { printf("test test"); }
$ gcc -c test1.c
$ gcc -c test2.c
$ gcc test1.o test2.o -o test
$ ./test
test test
#include <iostream> using namespace std; int main() { cout << "ようこそC++!\n"; cout << "lets start c++!\n"; return 0; }
coutはstandard outputと結び付けられ、 は表示を意味する
iostreamは画面出力の機能などを表す
coutは本来、using namespace stdでstc.coutと書くが、省略もできる。
int main() { cout << 1 << 2 << 3 << '\n' << 4 << 5 << '\n'; return 0; }
c++では文字、数字の表記をリテラルと呼ぶ。リテラルの他に、キーワード、識別子、演算子、区切り子などがある。
リテラルは”で囲む
#include <iostream> using namespace std; int main() { cout << 'A' << '\n'; cout << "welcome to C++!\n"; cout << 123 << '\n'; return 0; }
エスケープシーケンス
int main() { cout << "円記号を表示する:" << '\\' << '\n'; cout << "アポストロフィを表示する:" << '\'' << '\n'; return 0; }
$ g++ -o sample sample.cpp && ./sample
円記号を表示する:\
アポストロフィを表示する:’
文字コード
int main() { cout << "8進数101の文字コードを持つ文字は" << '\101' << "です\n"; cout << "16進数61の文字コードを持つ文字は" << '\x61' << "です\n"; return 0; }
$ g++ -o sample sample.cpp && ./sample
8進数101の文字コードを持つ文字はAです
16進数61の文字コードを持つ文字はaです
文字リテラルは”でくくる。
数値には整数と浮動小数点があり、それぞれinteger literal, floating literalと呼ぶ
int main() { cout << "10進数の10は" << 10 << "です\n"; cout << "8進数の10は" << 010 << "です\n"; cout << "16進数の10は" << 0x10 << "です\n"; cout << "16進数のFは" << 0xF << "です\n"; return 0; }
$ g++ -o sample sample.cpp && ./sample
10進数の10は10です
8進数の10は8です
16進数の10は16です
16進数のFは15です
int main() { cout << 123 << '\n'; cout << "\\" << "100もらった\n"; cout << "また明日\n"; return 0; }
8進数と16進数
#include <iostream> using namespace std; int main() { // 8進数 cout << 06 << '\n'; cout << 024 << '\n'; cout << 015 << '\n'; // 16進数 cout << 0x6 << '\n'; cout << 0x14 << '\n'; cout << 0xd << '\n'; }
16進数はビットコインで基本となってますね。
$ sudo apt install build-essential
$ gcc –version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ –version
g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#include <iostream> using namespace std; int main() { cout << "ようこそC++!\n"; return 0; }
$ g++ -o sample sample.cpp && ./sample
ようこそC++!
cc コンパイラオプション
% cc [<オプション>] <ファイル名> [<ライブラリ>]
srcdir: コンパイルされるソースに対するディレクトリ
.ac: ユーザーのアクセス権限を証明
#!/bin/bash cat >>Makefile.am < # ビルドしてインストール bin_PROGRAMS=test #コンパイルする際のコンパイルオプション #../configureなどルートディレクトリ以外で実行した時のインクルードディレクトリ test_CFLAGS=-g -l @srcdir@/include/ #test_LDADDはライブラリ test_LDADD= -lm #ソースコード test_SOURCES=test.c #ライブラリ用設定 include_HEADERS=test.h #ライブラリ作成する際のライブラリ名 lib_LIBRARIES=libtest.a #libtest.aのソースコード libtest_a_SOURCES #ビルドしないがインストールするファイル #prefixオプションで指定したディレクトリ以下の/share/パッケージ名に配置 pkgdata_DATA=setting #C言語からdesineとして参照 AM_CFLAGS= -DEVENTTABLE_CSV=""$(pkgdatadir)/setting"" #再帰的にmakeを実行 SUBDIRS= subdir subdir2/subsubdir EOF vim Makefile.am autoscan touch NEWS README AUTHORS ChangeLog awk '{if(/AC_INIT/){print "AC_INIT(FULL-PACKAGE-NAME, 0.0.1, name@hoge.jp)";print"AM_INIT_AUTOMAKE"}else{print $0}}' configure.scan > congifure.ac vim configure.ac aclocal autoheader autoconf automake -a -c
Concepts to know
-Structs, arrays, pointers, and reference types
-File I/O
-Use of command line parameters
-Pass-by-reference and pass-by-value
-Dynamic memory allocation using malloc()
-Use of C libraries
Helpful Skills related C
-Debugging programs
-Reading documentation
-Iterative design
-Good coding standards
#include<stdio.h> #include<stdlib.h> #include<stdbool.h> struct test_struct { int val; struct test_struct *next; } struct test_struct *head = NULL; struct test_struct *curr = NULL; struct test_struct* create_list(int val) { printf("\n creating list with headnode as [%d]\n", val); struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct)); if(NULL == ptr) { printf("\n Node creation failed \n"); return NULL; } ptr->val = val; ptr->next = NULL; head = curr = ptr; return ptr; } struct test_struct* add_to_list(int val, bool add_to_end) { if(NULL == head) { return (create_list(val)); } if(add_to_end) printf("\n Adding node to end of list with value [%d]\n",val); else printf("\n Adding node to beginning of list with value [%d]\n", val); struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct)); if(NULL == ptr) { printf("\n Node creation failed \n"); return NULL; } ptr->val = val; ptr->next = NULL; if(add_to_end) { curr->next = ptr; curr = ptr; } else { ptr->next = head; head = ptr; } return ptr; } struct test_struct* search_in_list(int val, struct test_struct **prev) { struct test_struct *ptr = head; struct test_struct *tmp = NULL; bool found = false; printf("\n Searching the list for value [%d] \n", val); while(ptr !=NULL) { if(ptr->val == val) { found = true; break; } else { tmp = ptr; ptr = ptr->next; } } if(true == found) { if(prev) *prev = tmp; return ptr; } else { return NULL; } } int delete_from_list(int val) { struct test_struct *prev = NULL; struct test_struct *del = NULL; printf("\n Deleting value [%d] from list\n",val); del = search_in_list(val,&prev); if(del == NULL) { return -1; } else { if(prev != NULL) prev->next = del->next; if(del == curr) { curr = prev; } else if(del == head) { head = del->next; } } free(del); del = NULL; return 0; } void print_list(void) { struct test_struct *ptr = head; printf("\n ----Printing list Start---- \n"); while(ptr != NULL) { printf("\n [%d] \n",ptr->val); ptr = ptr->next; } printf("\n -------Printing list End ------ \n"); return; } int main(void) { int i = 0, ret = 0; struct test_struct *ptr = NULL; print_list(); for(i = 5; i<10; i++) add_to_list(i,true); print_list(); for(i =4; i>0; i--) add_to_list(i,false); print_list(); for(i = 1; i<10; i += 4) { ptr = search_in_list(i, NULL); if(NULL == ptr) { printf("\n Search [val = %d] failed, no such element found\n",i); } else { printf("\n Search passed [val = %d]\n", ptr->val); } print_list(); ret = delete_from_list(i); if(ret != 0) { printf("\n delete [val = %d] failed, no such element found\n",i); } else { printf("\n delete [val = %d] passed \n", i); } print_list(); } return 0; }
[vagrant@localhost c]$ gcc -v Using built-in specs. Target: x86_64-redhat-linux コンフィグオプション: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux スレッドモデル: posix gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)
#include <stdio.h> int main(void){ printf("hello world!\n"); return 0; }
[vagrant@localhost c]$ gcc -o hello hello.c [vagrant@localhost c]$ ll 合計 12 -rwxrwxr-x. 1 vagrant vagrant 6425 11月 10 06:31 2016 hello -rw-rw-r--. 1 vagrant vagrant 84 11月 10 06:30 2016 hello.c [vagrant@localhost c]$ ./hello hello world!
なお、Cでつまづきやすいと言われているポインタですが、アドレスの値を定義して(参照渡し)、データ型よりもメモリの消費を節約する仕組みで、より高速なプログラムが書けるようになります。
割り当て済み猟奇のサイズを変更することができる。
#include#include #define BUFF_SIZE 256 int main(void) { int i; unsigned char *pmem = NULL, *pmemsave = NULL, *pmemnew = NULL; pmemsave = pmem = (unsigned char *)malloc(BUFF_SIZE); if (pmem == NULL){ fprintf(stderr, "メモリ割り当てに失敗しました。\n"); exit(EXIT_FAILURE); } for (i = 0; i < BUFF_SIZE; i++) *pmem++ = (unsigned char)i; pmem = pmemsave; for (i = 0; i < BUFF_SIZE; i++) printf("%u ", *pmem++); printf("\n"); pmemnew = realloc(pmemsave, BUFF_SIZE * 2); if (pmemnew != NULL){ pmem = pmemnew; for (i = 0; i < BUFF_SIZE * 2; i++) printf("%u ", *pmem++); printf("\n"); free(pmemnew); pmemnew = NULL; } else { free(pmemsave); pmemsave = NULL; fprintf(stderr, "メモリの再割り当てに失敗しました\n"); exit(EXIT_FAILURE); } return 0; }
/*****************************/ /*filename:bbi_misc.cpp 雑関数*/ /*****************************/ #include "bbi.h" #include "bbi_prot.h" string dbl_to_s(double d) { ostringstream ostr; ostr << d; return ostr.str(); } string err_msg(const string& a, const string& b) { if (a == "") return b + "が必要です。" if(b == "") return a + "が不正です。"; return b + "が" + a + "の前に必要です。"; } void err_exit(Tobj a, Tobj b, Tobj c, Tobj d) { Tobj ob[5]; ob[1] = a; ob[2] = b; ob[3] = c; ob[4]= d; cerr << "line:" << get_lineNo() << "ERROR"; for (int i=1; i<=4 && ob[i].s! = "\1"; i++){ if (ob[i].type == 'd') cout << ob[i].d; if (ob[i].type == 's') cout << ob[i].s; } cout << endl; exit(1); }
/**************************************************/ /*filename:bbi_code.cpp メモリ管理と構文チェックと実行*/ /**************************************************/ #include "bbi.h" #include "bbi_prot.h" CodeSet code; int startPc; int Pc = -1; int baseReg; int spReg; int maxLine; vectorintercode; char *code_ptr; double return value; bool break_Flg, return_Flg, exit_Flg; Mymemory Dmem; vector strLITERAL; vector nbrLITERAL; bool syntaxChk_mode = false; extern vector Gtable; class Mystack { private: stack st; public: void push(double n){ st.push(n); } int size() { return (int)st.size(); } bool empty() { return st.empty(); } double pop(){ if (st.empty()) err_exit("stack underflow"); double d = st.top(); st.pop(); return d; } }; void syntaxChk() { syntaxChk_mode = true; for (Pc=1; Pc<(int)intercode.size(); Pc++){ code = firstCode(Pc); switch(code.kind){ case Func: case Option: case Var: break; case Else: case End: case Exit: code =nextCode(); chk_EofLine(); break; case If: case Elif: case While: code = nextCode(); (void)get_expression(0, EofLine); break; case For: code = nextCode(); (void)get_memAdrs(code); (void)get_expression('=', 0); (void)get_expression(To, 0); if (code.kind == Step) (void)get_expression(Step, 0); chk_EofLine(); break; case Fcall: fncCall_syntax(code.symNbr); chk_EofLine(); (void)stk.pop(); break; case Print: case Println: sysFncExec_syntax(code.kind); break; case Gvar: case Lvar: (void)get_memAdrs(code); (void)get_expression('-', EofLine); break; case Return: code = nextCode(); if (code.kind!='?' && code.kind!=EofLine)(void)get_expression(); if(code.kind=='?')(void)get_expression('?', 0); chk_EofLine(); break; case Break: code = nextCode(); if (code.kind == '?') (void)get_expression('?', 0); chk_EofLine(); break; case EofLine: break; default: err_exit("不正な記述です: ", kind_to_s(code.kind)); } } syntaxChk_mode = false; } void set_startPc(int n) { startPc = n; } void execute() { baseReg = 0; spReg = Dmem.size(); Dmem.resize(spReg+1000); break_Flg = return_Flg = exit_Flg = false; Pc = startPc; maxLine = intercode.size() - 1; while (Pc<=maxLine && !exit_Flg){ statement(); } Pc = -1; } void statement() { CodeSet save; int top_line, end_line, varAdrs; double wkVal, endDt, stepDt; if (Pc>maxLine || exit_Flg) return; code = save = firstCode(Pc); top_line = Pc; end_line = code.jmpAdrs; if (code.kind == If) end_line = endline_of_If(Pc); switch(code.kind){ case If: if (get_expression(If, 0)){ ++Pc; block(); Pc = end_line + 1; return; } Pc = save.jmpAdrs; while (lookCode(Pc) == Elif){ save = firstCode(Pc); code = nextCode(); if (get_expression()){ ++Pc; block(); Pc = end_line + 1; return; } Pc = save.jmpAdrs; } if (lookCode(Pc) == Else){ ++Pc; block(); Pc = end_line + 1; return; } ++Pc; break; case While: for(;;){ if (!get_expression(While, 0)) break; ++Pc; block(); if (break_Flg || return_Flg || exit_Flg){ break_Flg = false; break; } Pc = top_line; code = firstCode(Pc); } Pc = end_line + 1; break; case For: save = nextCode(); varAdrs = get_memAdrs(save); expression('=', 0); set_dtTyp(save, DBL_T); Dmem.set(varAdrs, stk.pop()); endDt = get_expression(To, 0); if (code.kind == Step) stepDt = get_expression(Step, 0); else stepDt = 1.0; for(;; PC=top_line){ if (Dmem.get(varAdrs) > endDt) break; } else { if (Dmem.get(varAdrs) < endDt) break; } ++Pc; block(); if (break_Flg || return_Flg || exit_Flg) { break_Flg = false; break; } Dmem.add(varAdrs, stepDt); } Pc = end_line+1; break; case Fcall: fncCall(code.symNbr); (void)stk.pop(); ++Pc; break; case Func: Pc = end_line + 1; break; case Print: case Println: sysFncExec(code.kind); ++Pc; break; case Gvar: case Lvar: varAdrs = get_memAdrs(code); expression('=', 0); set_dtTyp(save, DBL_T); Dmem.set(varAdrs, stk.pop()); ++Pc; break; case Return: wkVal = returnValue; code = nextCode(); if (code.kind!='?' && code.kind!=EofLine) wkVal = get_expression(); post_if_set(return_Flg); if (return_Flg) returnValue = wkVal; if(!return_Flg) ++Pc; break; case Break: code = nextCode(); post_if_set(break_Flg); if(!break_Flg) ++ Pc; break; case Exit: code = nextCode(); exit_Flg = true; break; case Option: case Var: case EofLine: ++Pc; break; default: err_exit("不正な記述です:", kind_to_s(code.kind)); } } void block() { TknKind k; while (!break_Flg && !return_Flg && !exit_Flg){ k = lookCode(Pc); if (k==Elif || k==Else || k==End) break; statement(); } } double get_expression(int kind1, int kind2) { expression(kind1, kind2); return stk.pop(); } void expression(int kind1, int kind2) { if (kind1 != 0) code =chk_nextCode(code, kind1); expression(); if (kind2 != 0) code = chk_nextCode(code, kind2); } void expression() { term(1); } void term(int n) { TknKind op; if (n == 7){ factor(); return; } term(n+1); while(n == opOrder(code.kind)){ op = code.kind; code = nextCode(); term(n+1); if (syntaxChk_mode){ stk.pop(); stk.pop(); stk.push(1.0); } else binaryExpr(op); } } void factor() { TknKind kd = code.kind; if (syntaxChk_mode){ switch (kd){ case Not: case Minus: case Plus: code = nextCode(); factor(); stk.pop(); stk.push(1.0); break; case Lparen: expression('(', ')'); break; case IntNum: case DblNum: stk.push(1.0); code = nextCode(); break; case Gvar: case Lvar: (void)get_memAdrs(code); stk.push(1.0); break; case Toint: case Input: sysFncExec_syntax(kd); break; case Fcall: fncCall_syntax(code.symNbr); break; case EofLine: err_exit("式が不正です。"); default: err_exit("式誤り:", kind_to_s(code)); } return; } switch (kd){ case Not: case Minus: case Plus: code = nextCode(); factor(); if (kd == Not) stk.push(!stk.pop()); if (kd == Minus) stk.push(-stk.pop()); break; case Lparen: expression('(', ')'); break; case IntNum: case DblNum: stk.push(code.dblVal); code = nextCode(); break; case Gvar: case Lvar: chk_dtTyp(code); stk.push(Dmem.get(get_memAdrs(code))); break; case Toint: case Input: sysFncExec(kd); break; case Fcall: fncCall(code.symNbr); break; } } int opOrder(TknKind kd) { switch(kd){ case Multi: case Divi: case Mod: case IntDivi: return 6; case Plus: case Minus: return 5; case Less: case LessEq: case Great: case GreatEq: return 4; case Equal: case NotEq: return 3; case And: return 2; case Or: return 1; default: return 0; } } void binaryExpr(TknKind op) { double d = 0, d2 = stk.pop(), dl = stk.pop(); if ((op == Divi || op == Mod || op==IntDivi) && d2 == 0) err_exit("ゼロ除算です。"); switch(op){ case Plus: d = d1 + d2; break; case Minus: d = d1 - d2; break; case Multi: d = d1 * d2; break; case Divi: d = d1 / d2; break; case Mod: d = (int)d1 % (int)d2; break; case IntDivi: d = (int)d1 / (int)d2; break; case Less: d = d1 < d2; break; case LessEq: d = d1 <= d2; break; case Great: d = d1 > d2; break; case GreatEq: d = d1 >= d2; break; case Equal: d = d1 == d2; break; case NotEq: d = d1 != d2; break; case And: d = d && d2; break; case Or: d = d1 || d2; break; } stk.push(d); } void post_if_set(bool& flg) { if (code.kind == EofLine){flg = true; return; } if (get_expression('?', 0)) flg = true; } void fncCall_syntax(int fncNbr) { int argCt = 0; code = nextCode(); code = chk_nextCode(code, '('); if (code.kind != ')'){ for (;; code=nextCode()){ (void)get_expression(); ++argCt; if (code.kind != ',') break; } } code = chk_nextCode(code, ')'); if (argCt != Gtable[fncNbr].args) err_exit(Gtable[fncNbr].name, "関数の引数個数が誤っています。"); stk.push(1.0); } void fncCall(int fncNbr) { int n, argCt = 0; vector vc; nextCode(); code = nextCode(); if (code.kind != ')'){ for(;; code=nextCode()){ expression(); ++argCt; if(code.kind != ',') break; } } code = nextCode(); for (n = 0; n aryLen; code = nextCode(); if (len == 0) return adr; d = get_expression('[', ']'); if ((int)d != d)err_exit("添字は端数のない数字で指定してください。"); if (syntaxChk_mode) return adr; index = (int)d; line = cd.jmpAdrs; cd = firstCode(line); if (cd.kind==Elif || cd.kind==Else) continue; if(cd.kind == End) break; return adr + index; } int get_topAdrs(const CodeSet& cd) { switch(cd.kind){ case Gvar: return tableP(cd)->adrs; case Lvar: return tableP(cd)->adrs + baseReg; default: err_exit("変数名が必要です:", kind_to_s(cd)); } return 0; } int endline_of_If(int line) { CodeSet cd; char *save = code_ptr; cd = firstCode(line); for(;;){ if(index < 0 || len <= index) err_exit(index, "は添字範囲外です(添字範囲:0-", len-1, ")"); } code_ptr = save; return line; } void chk_EofLine() { if (code.kind != EofLine) err_exit("不正な記述です:", kind_to_s(code)); } TknKind lookCode(int line) { return (TknKind)(unsigned char)intercode[line][0]; } CodeSet chk_nextCode(const CodeSet& cd, int kind2) { if (cd.kind != kind2){ if (kind2 == EofLine) err_exit("不正な記述です: ", kind_to_s(cd)); if (cd.kind == EofLine) err_exit(kind_to_s(kind2), "が必要です。"); err_exit(kind_to_s(kind2)+ "が"+ kind_to_s(cd) + "の前に必要です。"); } return nextCode(); } CodeSet firstCode(int line) { code_ptr = intercode[line]; return nextCode(); } CodeSet nextCode() { TknKind kd; short int jmpAdrs, tblNbr; if (*code_ptr == '\0') return CodeSet(EofLine); kd = (TknKind)*UCHAR_P(code_ptr++); switch Func: case While: case For: case If: case Elif: case Else: jmpAdrs = *SHORT_P(code_ptr); code_ptr += SHORT_SIZ; return CodeSet(kd, -1, jmpAdrs); case String: tblNbr = *SHORT_P(code_ptr); code_ptr += SHORT_SIZ; return CodeSet(kd, strLITERAL[tblNbr].c_str()); case IntNum: case DblNum: tblNbr = *SHORT_P(code_ptr); code_ptr += SHORT_SIZ; return CodeSet(kd, nbrLITERAL[tblNbr]); case Fcall: case Gvar: case Lvar: tblNbr = *SHORT_P(code_ptr); code_ptr += SHORT_SIZ; return CodeSet(kd, tblNbr, -1); default: return CodeSet(kd); } } void chk_dtTpy(const CodeSet& cd) { if (tableP(cd)->dtTyp == NON_T) err_exit("初期化されていない変数が使用されました:", kind_to_s(cd)); } void set_dtTyp(const CodeSet& cd, char typ) { int memAdrs = get_topAdrs(cd); vector ::iterator p = tableP(cd); if (p->dtTyp != NON_T)return: p->dtTyp = typ; if (p->aryLen != 0){ for (int n=0; n < p->aryLen; n++){ Dmem.set(memAdrs+n, 0);} } } int set_LITERAL(double d) { for (int n=0; n<(int)nbrLITERAL.size(); n++){ if (nbrLITERAL[n] == d) return n; } nbrLITERAL.push_back(d); return nbrLITERAL.size() - 1; } int set_LITERAL(const string& s) { for (int n=0; n<(int)strLITERAL.size(); n++){ if (strLITERAL[n] == s) return n; } strLITERAL.push_back(s); return strLITERAL.size() -1; }
/**************************************/ /* filename:bbi_tbl.cpp 記号表処理 */ /**************************************/ #include "bbi.h" "include "bbi_prot.h" vector<SymTbl> Gtable; vector<SymTbl> Ltable; int startLtable; int enter(SymTbl& tb, SymKind kind) { int n, mem_size; bool isLocal = is_localName(tb.name, kind); extern int localAdrs; extern Mymemory Dmem; mem_size = tb.aryLen; if (mem_size == 0) mem_size = 1; if (kind!=varId && tb.name[0] == '$') err_exit("変数名以外で$を使うことはできません:", tb.name); tb.nmKind = kind; n = -1; if (kind == fncId) n = searchName(tb.name, 'G'); if (kind == paraId) n = searchName(tb.name, 'L'); if (n != -1) err_exit("名前が重複しています:", tb.name); if(kind == fncId) tb.adrs = get_lineNo(); else { if (isLocal){ tb.adrs = localAdrs; localAdrs += mem_size; } else { tb.adrs = Dmem.size(); Dmem.resize(Dmem.size() + mem_size); } } if (isLocal){ n = Ltable.size(); Ltable.push_back(tb); } else { n= Gtable.size(); Gtable.push_back(tb); } return n; } void set_startLtable() { startLtable = Ltable.size(); } bool is_localName(const string& name, SymKind kind) { if (kind == paraId) return true; if (kind == varId){ if (is_localScope() && name[0]!='$') return true; else return false; } return false; } int searchName(const string& s, int mode) { int n; switch (mode){ caes 'G': for (n=0; n<(int)Gtable.size(); n++){ if (Gtable[n].name == s) return n; } break; case 'L': for (n=startLtable; n<(int)Ltable.size(); n++) { if(Ltable[n].name == s) return n; } break; case 'F': n = searchName(s, 'G'); if(n != -1 && Gtable[n].nmKind==fncId) return n; break; case 'V': if (searchName(s, 'F') != -1) err_exit("関数名と重複しています: ", s); if (s[0] == '$') return searchNAme(s, 'G'); if (is_localScope()) return searchName(s, 'L'); else return searchName(s, 'G'); } return -1; } vector<SymTbl>::iterator tableP(const CodeSet& cd) { if (cd.kind == Lvar) return Ltable.begin() + cd.symNbr; return Gtable.begin() + cd.symNbr; }