3月15日に卒業式が行われ,当研究室より2018年度卒研生5名が卒業しました。
新メンバー追加(卒研入門2018)
祝卒業2018(学士6名)
C言語認定試験(2級出題範囲)
参考(2級出題範囲)
出題内容 | ||
定数 | 浮動小数点定数 | 指数形式を許す 浮動小数点接尾語はf、l、F、Lのいずれか |
---|---|---|
整数定数 | 整数接尾語として長語接尾語(l、L)を含む | |
文字定数 | 拡張表記は8進拡張表記、16進拡張表記を含む | |
文字列リテラル | 拡張表記は8進拡張表記、16進拡張表記を含む | |
列挙定数 | ||
演算子 | ビット演算子、条件演算子、代入演算子、キャスト演算子、ポインタ/アドレス演算子、構造体演算子、sizeof演算子 | |
宣言指定子 | void、short、long、float、double、構造体共用体指定子(struct、union)、列挙型指定子(enum)、型修飾子(const)、typedef | |
変数 | 上記型指定子の単純変数、配列 | |
外部定義 | ||
プリプロセッサ機能 | ファイルの包含 | |
ライブラリ関数 |
|
|
|
||
|
||
|
||
その他 |
|
※3級出題範囲含む
注)各級とも日本工業規格 (JIS) X3010 で出題・解答する。
C言語認定試験(3級出題範囲)
C言語プログラミング能力認定試験
(C-Language Programming Skills Qualification Test)
http://www.sikaku.gr.jp/js/cp/
C言語認定試験とは
C言語を駆使した応用プログラムの作成能力を認定
C言語は、記述の自由度が高く、使用可能なプラットホームが多いなど、使用できる場面が多いことから、現在最も広く普及しているプログラミング言語です。このC言語のプログラミング能力の測定を目的に、1992年より開始されたのがサーティファイ 情報処理能力認定委員会が主催する「C言語プログラミング能力認定試験」です。
保有スキルのレベルに合わせた3段階の認定基準を設けることにより、これから新たにプログラミングの学習を始める方から、現在プログラマやシステム・エンジニアとして既に活躍されている高度IT技術者の方まで、幅広い皆様から受験いただいています。
初学者から、ビジネスシーンで活躍できるプログラマまで、幅広いスキルを測定
「C言語プログラミング能力認定試験」は、これからプログラミングを学び始める方を対象とした「3級」から、プログラマやシステム・エンジニアとして活躍されている方の保有スキルを客観的にアピールできる「1級」まで、幅広いスキルを測定しています。
特に「1級」では、実際にPCを使用して、プログラムの仕様変更やこれに伴うプログラミング作成(コーディング・コンパイル・デバッグ)を行う、極めて実践的な資格・検定試験として、IT業界でも高く評価されています。
基本情報技術者試験の午後の試験対策としても有効
「C言語プログラミング能力認定試験」の「2級」及び「3級」は、経済産業省認定「基本情報技術者試験」の「午後問題」の出題形式も意識して作成しています。そのため、「基本情報技術者試験」の学習と連動した活用も多く見られます。保有スキルのレベルに応じた級位取得を目標としていただくことで、C言語のプログラミング能力を高めるだけではなく、「基本情報技術者試験」の合格にもつなげていくことができます。
C言語認定試験について
主催・認定
試験名
C言語プログラミング能力認定試験
(C-Language Programming Skills Qualification Test)
試験目的
C言語を駆使して応用プログラム(言語処理系、ユーティリティなど)を作成する能力を認定します。
認定基準
一級 | C言語を駆使し、応用プログラム(言語処理系、ユーティリティなど)が作成できる能力を有する。また使用しているOSについて理解をしている。 |
二級 | 小規模のプログラム(500行程度)が適切に(理路整然、簡潔、正しく、速く)書ける。また各種基本アルゴリズムを理解している。 |
三級 | C言語の概念を理解し、簡単なプログラムが書ける。 |
参考(3級出題範囲)
出題内容 | ||
定数 | 整数定数 | 10進定数、8進定数、16進定数 整数接尾語は符号無し接尾語(u、U)のみ |
---|---|---|
文字定数 | ワイド文字定数(L’c文字の列’)を除く 拡張表記は単純拡張表記のみ |
|
文字列リテラル | ワイド文字列リテラル(L”s文字の列”)を除く 拡張表記は単純拡張表記のみ |
|
演算子 | 算術演算子、インクリメント演算子、デクリメント演算子、(算術の)代入演算子、関係演算子、等値演算子、論理関係演算子、括弧演算子、コンマ演算子 | |
型指定子 | char、int、unsigned、signed | |
変数 |
|
|
基本制御文 | break、continue、do、for、if、return、switch、while | |
プリプロセッサ機能 | #define、#include | |
ライブラリ関数 |
|
|
|
||
その他 | Cの歴史と特徴 |
現在使用するC言語教科書には、文字操作関数<ctype.h>の内容について不足するので、
[amazonjs asin=”479815038X” locale=”JP” ]
下記のサイトを参考にしてください。
- http://www.c-tipsref.com/reference/ctype.html
- http://www.bohyoh.com/CandCPP/C/Library/ctype_h.html
a C HTTP Client
C#やJavaでは簡単にhttp Clientプログラムができる。C言語ではソケットを作成するところから必要です。またWindowsとLinux両方対応するように書いたのでプログラムが長くなる。
(bcc32で動作確認済み)
プログラムは、最初にsocketを生成してWebサーバに接続し、テキスト形式でHTTPリクエストメッセージを作成してWebサーバに送信する。
HTTPリクエストメッセージは、複数行から成り立つ一連のデータ列。ここでいう1行とは、終端にCR(キャリッジリターン、16進の0x0d)とLF(ラインフィード、16進の0x0a)を持つデータの単位を示す。ほぼ、通常のテキスト・データの1行と等しくなる。メッセージ・ヘッダとメッセージボディ部に分かれ、両者は空行(単独のCR+LF)で分割される。
httpを理解するには、telnetで手入力でHTTPをしゃべってみるがいい方法。
https://www.softel.co.jp/blogs/tech/archives/263
まずプログラムをリストする:
#include <stdio.h> /* printf, sprintf */ #include <stdlib.h> /* exit, atoi, malloc, free */ // #include <unistd.h> /* read, write, close */ #include <string.h> /* memcpy, memset */ #ifdef __linux__ #include <sys/socket.h> /* socket, connect */ #include <netdb.h> /* struct hostent, gethostbyname */ #include <netinet/in.h> /* struct sockaddr_in, struct sockaddr */ #elif _WIN32 #include <winsock2.h> #include <ws2tcpip.h> #include <windows.h> #pragma comment(lib,"ws2_32.lib") //Winsock Library #else #endif struct hostent *server; struct sockaddr_in serv_addr; int bytes, sent, received; char response[4096]; int portno; char *host; char *path; void error(const char *msg) { perror(msg); exit(0); } #ifdef _WIN32 win_send_http(char *message){ WSADATA wsa; SOCKET s; printf("\nInitialising Winsock..."); if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) { printf("Failed. Error Code : %d",WSAGetLastError()); return 1; } printf("Initialised.\n"); //Create a socket if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET) { printf("Could not create socket : %d" , WSAGetLastError()); } printf("Socket created.\n"); server = gethostbyname(host); memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(portno); memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length); //Connect to remote server if (connect(s , (struct sockaddr *)&serv_addr , sizeof(serv_addr)) < 0) { printf("connect failed with error code : %d" , WSAGetLastError()); return 1; } puts("Connected"); if( send(s , message , strlen(message) , 0) < 0) { printf("Send failed with error code : %d" , WSAGetLastError()); return 1; } puts("Data Send\n"); //Receive a reply from the server if((received = recv(s , response , 2000 , 0)) == SOCKET_ERROR) { printf("recv failed with error code : %d" , WSAGetLastError()); } puts("Reply received\n"); //Add a NULL terminating character to make it a proper string before printing response[received] = '\0'; puts(response); closesocket(s); WSACleanup(); return 0; // everything OK } #endif #ifdef __linux__ linx_send_http(message) { int sockfd; int total; total = strlen(message); /* lookup the ip address */ server = gethostbyname(host); if (server == NULL) error("ERROR, no such host"); /* create the socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); /* fill in the structure */ memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(portno); memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length); /* connect the socket */ if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); /* send the request */ sent = 0; do { bytes = write(sockfd,message+sent,total-sent); if (bytes < 0) error("ERROR writing message to socket"); if (bytes == 0) break; sent+=bytes; } while (sent < total); /* receive the response */ memset(response, 0, sizeof(response)); total = sizeof(response)-1; received = 0; printf("Response: \n"); do { printf("%s", response); memset(response, 0, sizeof(response)); bytes = recv(sockfd, response, 1024, 0); if (bytes < 0) printf("ERROR reading response from socket"); if (bytes == 0) break; received+=bytes; } while (1); if (received == total) error("ERROR storing complete response from socket"); /* close the socket */ close(sockfd); return 0; // everything OK } #endif int main(int argc,char *argv[]) { int i; char message[4096]; portno = atoi(argv[2])>0?atoi(argv[2]):80; host = strlen(argv[1])>0?argv[1]:"localhost"; path = strlen(argv[4])>0?argv[4]:"/"; if (argc < 5) { puts("Parameters: <host> <port> <method> <path> [<data> [<headers>]]"); exit(0); } /* How big is the message? */ if(!strcmp(argv[3],"GET")) { if(argc>5) sprintf(message,"%s %s%s%s HTTP/1.0\r\nHost: %s\r\n", strlen(argv[3])>0?argv[3]:"GET", /* method */ path, /* path */ strlen(argv[5])>0?"?":"", /* ? */ strlen(argv[5])>0?argv[5]:"",host); /* query string */ else sprintf(message,"%s %s HTTP/1.0\r\nHost: %s\r\n", strlen(argv[3])>0?argv[3]:"GET", /* method */ path,host); /* path */ for(i=6;i<argc;i++) /* headers */ {strcat(message,argv[i]);strcat(message,"\r\n");} strcat(message,"\r\n"); /* blank line */ } else { sprintf(message,"%s %s HTTP/1.0\r\nHost: %s\r\n", strlen(argv[3])>0?argv[3]:"POST", /* method */ path,host); /* path */ for(i=6;i<argc;i++) /* headers */ {strcat(message,argv[i]);strcat(message,"\r\n");} if(argc>5) { sprintf(message+strlen(message),"Content-Length: %d\r\n",(int)strlen(argv[5])); sprintf(message+strlen(message),"Content-Type: application/x-www-form-urlencoded\r\n"); } strcat(message,"\r\n"); /* blank line */ if(argc>5) strcat(message,argv[5]); /* body */ sprintf(message,"%s %s HTTP/1.0\r\nHost: %s\r\n", strlen(argv[3])>0?argv[3]:"POST", /* method */ path,host); /* path */ for(i=6;i<argc;i++) /* headers */ {strcat(message,argv[i]);strcat(message,"\r\n");} if(argc>5) { sprintf(message+strlen(message),"Content-Length: %d\r\n",(int)strlen(argv[5])); sprintf(message+strlen(message),"Content-Type: application/x-www-form-urlencoded\r\n"); } strcat(message,"\r\n"); /* blank line */ if(argc>5) strcat(message,argv[5]); /* body */ } printf("Processed\n"); /* What are we going to send? */ printf("Request:\n%s\n",message); #ifdef _WIN32 win_send_http(message); #endif #ifdef __linux__ linx_send_http(message); #endif return 0; }
このプログラムを利用して、例のTinyWebDBを読み書きしてみる。
まずPostで、データを書き込む
C:\Users\chen\Documents\C\http-client>http-client-3 tinydb.work 80 POST /api/storeavalue/ “tag=presentationtimer&value=Just a TEST from C3”
Process 2 Allocating... Processed Request: POST /api/storeavalue/ HTTP/1.0 Host: tinydb.work Content-Length: 47 Content-Type: application/x-www-form-urlencoded tag=presentationtimer&value=Just a TEST from C3 Initialising Winsock...Initialised. Socket created. Connected Data Send Reply received HTTP/1.1 200 OK Server: nginx Date: Tue, 12 Dec 2017 06:56:12 GMT Content-Type: application/json Content-Length: 52 Connection: close X-Powered-By: PHP/5.6.31 Vary: Cookie Set-Cookie: wfvt_2029330401=5a2f7d8c36e15; expires=Tue, 12-Dec-2017 07:26:12 GMT; Max-Age=1800; path=/; httponly Expires: Mon, 26 Jul 1997 05:00:00 GMT Cache-Control: no-cache, must-revalidate ["STORED","presentationtimer","Just a TEST from C3"]
次は、Getで、書き込んだデータを取得
C:\Users\chen\Documents\C\http-client>http-client-3 tinydb.work 80 POST /api/getvalue/ “tag=presentationtimer”
Process 2 Allocating... Processed Request: POST /api/getvalue/ HTTP/1.0 Host: tinydb.work Content-Length: 21 Content-Type: application/x-www-form-urlencoded tag=presentationtimer Initialising Winsock...Initialised. Socket created. Connected Data Send Reply received HTTP/1.1 200 OK Server: nginx Date: Tue, 12 Dec 2017 06:57:10 GMT Content-Type: application/json Content-Length: 51 Connection: close X-Powered-By: PHP/5.6.31 Vary: Cookie Set-Cookie: wfvt_2029330401=5a2f7dc61d61c; expires=Tue, 12-Dec-2017 07:27:10 GMT; Max-Age=1800; path=/; httponly Expires: Mon, 26 Jul 1997 05:00:00 GMT Cache-Control: no-cache, must-revalidate ["VALUE","presentationtimer","Just a TEST from C3"]
Dump file
DUMP
で出力された内容を ダンプリスト と呼ぶ
ダンプリスト左端はアドレス(ファイル先頭からの位置)
ダンプリスト中央にある16進数(バイト)が列挙されてる部分がマシン語プログラム(バイトコード)を表している。
ダンプリスト右端は、バイトコードをキャラクタコードで表現したときの内容。ただしバイトで表現可能な数値はキャラクタコードの範疇を超えることがあるため、そのような場合はピリオドで表現される。
dump.c
#include <stdio.h> int main(int argc, char* argv[]) { FILE *fp; unsigned char buf[16]; /* 読み込みバッファ */ unsigned long addr = 0; /* 先頭からのアドレス */ int readnum, i; if(argc <= 1) { printf("usage:dump filename\n"); return 1; } if(!(fp = fopen(argv[1], "rb"))) { printf("file open error.\n"); return 1; } while(1) { printf("%08x ", addr); readnum = fread(buf, 1, 16, fp); /* パイナリデータの表示 */ for(i = 0; i < readnum; i++) { if( i == 8) printf(" "); printf("%02x ", buf[i]); } for(i =readnum; i < 16; i++) { if(i == 8) printf(" "); printf(" "); } printf(" "); for(i = 0; i < readnum; i++) printf("%c", (32 <= buf[i] && buf[i] <= 126) ? buf[i] : '.'); printf("\n"); addr += 16; if(feof(fp)) break; } fclose(fp); return 0; }
公開講座2017「自分だけのスマホアプリを作ろ」
[GCC]C Compiler on Linux
C言語の最小限の開発環境を作る手順
- エディタをインストール
- コンパイラをインストール
- コンパイラにPATHを通す設定をする
エディタをインストール
Atomという新世代のエディター(Windows、Mac OS X、Linux対応)をインストールしてください。
コンパイラをインストール
LinuxでのC言語開発環境について解説しています。「GNU Compiler Collection」が一般的です。
それでは gcc をインストールしていきます。
Debian
Debianでは、apt-getコマンドを使ってgccをインストールします。
# apt-get install gcc
Ubuntu
UbuntuはDebianベースのディストリビューションなので、Debianと同じようにa apt-getコマンドを使います。ただ、Ubuntuにはrootユーザーという概念がないので、sudoコマンドでインストールしていきます。
$ sudo apt-get install gcc
CentOS
CentOSでは、yumコマンドを使ってgccをインストールします。
# yum install gcc
以上で、コンパイラ(gcc)のインストールは完了です。
コンパイラにPATHを通す設定をする
不要です。
ソースコードコンパイル
C言語プログラムのファイル名を「hello.c」というファイルを作成します。ファイルの中身は「Hello, World!」という文字列を出力するプログラムです。
hello.cをコンパイルします。
$ gcc hello.c
エラーが表示されなければ、OKです。
プログラムの実行
実行します。
$ ./a.out Hello, World
無事に実行できましたね。
[GCC]C Compiler on Windows
WindowsでgccをインストールするにはMinGWを利用した、C言語の最小限の開発環境を作る手順
- エディタをインストール
- コンパイラをインストール
- コンパイラにPATHを通す設定をする
エディタをインストール
Atom、VSCodeなど新世代のエディター(Windows、Mac OS X、Linux対応)をインストールしてください。
コンパイラをインストール
C言語コンパイラって幾つかありますが、visual studioはファイルサイズがデカいので却下です。gccのインストールをオススメします。gccはMacでもLinuxでもWindowsでも使えます。
コンパイラの違い一覧
システム | mingw-jp | Visual Studio .net | Borland C++ Builder |
---|---|---|---|
コンパイラ名 | gcc | cl | bcc32 |
オブジェクトファイルの拡張子 | .o | .obj | .obj |
実行ファイル名指定 | -o ファイル名 | -o ファイル名 | -eファイル名 |
make コマンド | mingw32-make | nmake | make |
依存ファイルマクロ | $^ | $** | $** |
WindowsでgccをインストールするにはMinGWというソフトを使う必要があります。
MinGW | Minimalist GNU for Windows
- MinGWのホームページで「Downloads」をクリック
- sourceforgeというサイトに飛びます
- 「Download mingw-get-setup.exe (86.5 kB)」をクリック
- exeファイルをダウンロード
- ダウンロードしたexeファイルを起動
- インストール自体は「Install」ボタンとか「Continue」ボタンをクリックするだけ
左のメニュー画面で「Basic Setup」を選択し、
- mingw-developer-toolkit
- mingw32-base
- mingw32-gcc-g++
- msys-base-32
を選んで、右クリックで「Mark for Installation」を選択します。
選び終わったら、上の「Installation」メニューから「Apply Changes」を選択すればインストールが始まります。
インストールが始まると、先ほど選択したパッケージがこのように変わります。
これでGCCが使えるようになりました。
コンパイラにPATHを通す設定をする
事前にgcc.exeの場所を探しておいてください。
MinGWをインストールする際に設定を変更していなければ C:MinGWbin
にあるはずです。
- エクスプローラー起動
- マイコンピューターで右クリック
- プロパティ選択
- システムの詳細設定
- 「環境変数」ボタン
- ユーザー環境変数 or システム環境変数にPathがあります
そのPathの最後に;C:¥MinGW¥bin
を追記
※「;
」を必ず付けてください
ユーザー環境変数とシステム環境変数の違い
- ユーザー環境変数:今ログインしているユーザーだけに有効
- システム環境変数:全てのユーザーに有効
お好きな方をお使いください。
コマンドプロンプトで gcc --help
と打ってみてください。
↓こんな感じのものが出てればgccが正常に使える状態です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
> gcc —help
Usage: gcc [options] file...
Options:
–pass–exit–codes Exit with highest error code from a phase
—help Display this information
—target–help Display target specific command line options
—help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]
Display specific types of command line options
(Use ‘-v –help’ to display command line options of sub–processes)
—version Display compiler version information
–dumpspecs Display all of the built in spec strings
–dumpversion Display the version of the compiler
–dumpmachine Display the compiler‘s target processor
-print-search-dirs Display the directories in the compiler’s search path
(※以下省略)
|
バージョンの確認
> gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/5.3.0/lto-wrapper.exe Target: mingw32 Configured with: ../src/gcc-5.3.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --prefix=/mingw --disable-win32-registry --target=mingw32 --with-arch=i586 --enable-languages=c,c++,objc,obj-c++,fortran,ada --enable-static --enable-shared --enable-threads=posix --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --enable-libstdcxx-debug --with-tune=generic --enable-libgomp --disable-libvtv --enable-nls Thread model: posix gcc version 5.3.0 (GCC)
ソースコードコンパイル
C言語プログラムのファイル名を「hello.c」というファイルを作成します。ファイルの中身は「Hello, World!」という文字列を出力するプログラムです。
以下のコマンドを打ってみてください。
> gcc hello.c -o hello.exe
そしたら hello.exe
が作られています。
プログラムの実行
コマンドプロンプトで実行ファイル名を入力してEnterキーを押すだけです。
コマンドプロンプトで、「hello.exe」を実行します。
> hello.exe Hello, World
このように「Hello, World」という文字列が出力されれば、OKです。
実行ファイルを指定した場合、指定したファイルを実行してください。